mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-06-23 12:15:00 -07:00
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.
This commit is contained in:
+9
-19
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 "<pointer value> -> " 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 "<pointer value>"
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user