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

This commit is contained in:
Ryan Fleury
2025-04-30 10:15:32 -07:00
parent 60b2195500
commit 10ff98faa8
4 changed files with 65 additions and 28 deletions
+5
View File
@@ -1075,6 +1075,11 @@ e_auto_hook_exprs_from_type_key(Arena *arena, E_TypeKey type_key)
continue; continue;
} }
U64 pattern_part_pos = str8_find_needle(type_string, scan_pos, n->string, 0); 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) if(pattern_part_pos >= type_string.size)
{ {
fits_this_type_string = 0; fits_this_type_string = 0;
+4 -6
View File
@@ -457,9 +457,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(default)
E_IRNode *new_tree = l.root; E_IRNode *new_tree = l.root;
E_TypeKey new_tree_type = r_type; E_TypeKey new_tree_type = r_type;
E_Mode mode = l.mode; E_Mode mode = l.mode;
if(l_restype_kind == E_TypeKind_Ptr || if(e_type_kind_is_pointer_or_ref(l_restype_kind))
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); new_tree = e_irtree_resolve_to_value(arena, l.mode, new_tree, l_restype);
if(l.mode != E_Mode_Null) 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 // rjf: unpack left-hand-side
E_Expr *lhs = expr->first; 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); e_msg_list_concat_in_place(&result.msgs, &lhs_irtree.msgs);
// rjf: try all IR trees in chain // 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_Expr *r_expr = expr->first;
E_TypeKey r_type = zero_struct; E_TypeKey r_type = zero_struct;
E_Space space = r_expr->space; 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); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs);
r_type = r_tree.type_key; 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 // rjf: evaluate operand tree
E_Expr *r_expr = expr->first; 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); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs);
// rjf: fill output // rjf: fill output
+36 -22
View File
@@ -2450,30 +2450,44 @@ E_TYPE_ACCESS_FUNCTION_DEF(slice)
{ {
Temp scratch = scratch_begin(&arena, 1); Temp scratch = scratch_begin(&arena, 1);
// rjf: compute bytecode of struct // rjf: compute ir tree for struct base
E_OpList lhs_oplist = e_oplist_from_irtree(scratch.arena, lhs_irtree->root); E_IRNode *struct_base_tree = &e_irnode_nil;
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));
{ {
lhs_expr->mode = lhs_irtree->mode; E_OpList lhs_oplist = e_oplist_from_irtree(scratch.arena, lhs_irtree->root);
lhs_expr->bytecode = lhs_bytecode; String8 lhs_bytecode = e_bytecode_from_oplist(arena, &lhs_oplist);
lhs_expr->type_key = e_type_key_unwrap(lhs_irtree->type_key, E_TypeUnwrapFlag_Lenses); 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))))
{ {
base_ptr_expr->string = ext->base_ptr_member->name; 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 // rjf: compute ir tree for base pointer value calculation
result = e_push_irtree_and_type_from_expr(arena, 0, 0, 1, idx_expr); 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); scratch_end(scratch);
}break; }break;
@@ -2492,7 +2506,7 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(slice)
} }
else if(accel->opl_ptr_member != 0 && accel->base_ptr_member != 0) 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}; E_TypeExpandInfo info = {0, count};
+20
View File
@@ -104,9 +104,11 @@ void optimized_struct_parameters_eval_tests(void);
// NOTE(allen): Type Coverage Eval // NOTE(allen): Type Coverage Eval
#include <vector> #include <vector>
#include <memory>
#include <stdint.h> #include <stdint.h>
raddbg_auto_view_rule(std::vector<?>, slice(_Mypair._Myval2)); raddbg_auto_view_rule(std::vector<?>, slice(_Mypair._Myval2));
raddbg_auto_view_rule(std::unique_ptr<?>, _Mypair._Myval2);
struct Basics struct Basics
{ {
@@ -1278,6 +1280,7 @@ struct Base
int x; int x;
int y; int y;
int z; int z;
Base(){x = 1; y = 2; z = 3;}
virtual ~Base() = default; virtual ~Base() = default;
virtual void Foo() = 0; virtual void Foo() = 0;
}; };
@@ -1308,6 +1311,7 @@ struct DerivedA : Base
{ {
float a; float a;
float b; float b;
DerivedA() {a = 123.f; b = 123.f;}
virtual void Foo() {a += 1;} virtual void Foo() {a += 1;}
virtual ~DerivedA() = default; virtual ~DerivedA() = default;
}; };
@@ -1316,6 +1320,7 @@ struct DerivedB : Base
{ {
double c; double c;
double d; double d;
DerivedB() {c = 123.0; d = 123.0;}
virtual void Foo() {c += 1;} virtual void Foo() {c += 1;}
virtual ~DerivedB() = default; virtual ~DerivedB() = default;
}; };
@@ -1556,6 +1561,21 @@ extended_type_coverage_eval_tests(void){
non_virtual_derived->x += 1; non_virtual_derived->x += 1;
non_virtual_derived->x += 1; non_virtual_derived->x += 1;
std::unique_ptr<Base> ridiculous_cplusplus_base_class = std::make_unique<DerivedB>();
std::vector<std::unique_ptr<Base>> ridiculous_cplusplus_array;
for(int i = 0; i < 1024; i += 1)
{
if((i & 1) == 1)
{
ridiculous_cplusplus_array.push_back(std::make_unique<DerivedA>());
}
else
{
ridiculous_cplusplus_array.push_back(std::make_unique<DerivedB>());
}
}
Base *base_array[1024] = {0}; Base *base_array[1024] = {0};
for(int i = 0; i < sizeof(base_array)/sizeof(base_array[0]); i += 1) for(int i = 0; i < sizeof(base_array)/sizeof(base_array[0]); i += 1)
{ {