mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-06-16 09:02:22 -07:00
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
This commit is contained in:
+61
-49
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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] =
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user