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) {