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