extend constructed types in eval system to support procedural construction of structs/unions/enums; can be used for synthetic evals in debugger frontend & ctrl layer

This commit is contained in:
Ryan Fleury
2024-08-13 13:04:05 -07:00
parent 6d30455e76
commit 0eff5aca06
7 changed files with 182 additions and 55 deletions
+2 -2
View File
@@ -31,8 +31,8 @@ DF_CORE_VIEW_RULE_EVAL_RESOLUTION_FUNCTION_DEF(array)
// rjf: apply array size to type
E_TypeKey pointee = e_type_ptee_from_key(type_key);
E_TypeKey array_type = e_type_key_cons(E_TypeKind_Array, pointee, array_size);
eval.type_key = e_type_key_cons(E_TypeKind_Ptr, array_type, 0);
E_TypeKey array_type = e_type_key_cons_array(pointee, array_size);
eval.type_key = e_type_key_cons_ptr(array_type);
}
}
scratch_end(scratch);
+2 -2
View File
@@ -53,7 +53,7 @@ e_autoresolved_eval_from_eval(E_Eval eval)
if(string_idx == 0) { string_idx = gvar->name_string_idx; }
if(string_idx != 0)
{
eval.type_key = e_type_key_cons(E_TypeKind_Ptr, e_type_key_basic(E_TypeKind_Void), 0);
eval.type_key = e_type_key_cons_ptr(e_type_key_basic(E_TypeKind_Void));
}
}
return eval;
@@ -117,7 +117,7 @@ e_dynamically_typed_eval_from_eval(E_Eval eval)
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(E_TypeKind_Ptr, derived_type_key, 0);
E_TypeKey ptr_to_derived_type_key = e_type_key_cons_ptr(derived_type_key);
eval.type_key = ptr_to_derived_type_key;
}
}
+3 -3
View File
@@ -631,7 +631,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr)
// rjf: generate
result.root = r_tree.root;
result.type_key = e_type_key_cons(E_TypeKind_Ptr, r_type_unwrapped, 0);
result.type_key = e_type_key_cons_ptr(r_type_unwrapped);
result.mode = E_Mode_Value;
}break;
@@ -928,7 +928,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr)
E_TypeKey ptr_type = ptr_tree->type_key;
if(ptr_is_decay)
{
ptr_type = e_type_key_cons(E_TypeKind_Ptr, direct_type, 0);
ptr_type = e_type_key_cons_ptr(direct_type);
}
E_IRNode *new_root = e_irtree_binary_op_u(arena, op, ptr_root, int_root);
result.root = new_root;
@@ -1039,7 +1039,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr)
case E_ExprKind_LeafStringLiteral:
{
String8 string = expr->string;
E_TypeKey type_key = e_type_key_cons(E_TypeKind_Array, e_type_key_basic(E_TypeKind_UChar8), string.size);
E_TypeKey type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_UChar8), string.size);
E_IRNode *new_tree = e_irtree_string_literal(arena, string);
result.root = new_tree;
result.type_key = type_key;
+11 -11
View File
@@ -57,9 +57,9 @@ global read_only S64 e_max_precedence = 15;
//~ rjf: Basic Helper Functions
internal U64
e_hash_from_string(String8 string)
e_hash_from_string(U64 seed, String8 string)
{
U64 result = 5381;
U64 result = seed;
for(U64 i = 0; i < string.size; i += 1)
{
result = ((result << 5) + result) + string.str[i];
@@ -84,7 +84,7 @@ e_string2num_map_make(Arena *arena, U64 slot_count)
internal void
e_string2num_map_insert(Arena *arena, E_String2NumMap *map, String8 string, U64 num)
{
U64 hash = e_hash_from_string(string);
U64 hash = e_hash_from_string(5381, string);
U64 slot_idx = hash%map->slots_count;
E_String2NumMapNode *existing_node = 0;
for(E_String2NumMapNode *node = map->slots[slot_idx].first; node != 0; node = node->hash_next)
@@ -112,7 +112,7 @@ e_num_from_string(E_String2NumMap *map, String8 string)
U64 num = 0;
if(map->slots_count != 0)
{
U64 hash = e_hash_from_string(string);
U64 hash = e_hash_from_string(5381, string);
U64 slot_idx = hash%map->slots_count;
E_String2NumMapNode *existing_node = 0;
for(E_String2NumMapNode *node = map->slots[slot_idx].first; node != 0; node = node->hash_next)
@@ -180,7 +180,7 @@ e_string2expr_map_make(Arena *arena, U64 slot_count)
internal void
e_string2expr_map_insert(Arena *arena, E_String2ExprMap *map, String8 string, E_Expr *expr)
{
U64 hash = e_hash_from_string(string);
U64 hash = e_hash_from_string(5381, string);
U64 slot_idx = hash%map->slots_count;
E_String2ExprMapNode *existing_node = 0;
for(E_String2ExprMapNode *node = map->slots[slot_idx].first;
@@ -206,7 +206,7 @@ e_string2expr_map_insert(Arena *arena, E_String2ExprMap *map, String8 string, E_
internal void
e_string2expr_map_inc_poison(E_String2ExprMap *map, String8 string)
{
U64 hash = e_hash_from_string(string);
U64 hash = e_hash_from_string(5381, string);
U64 slot_idx = hash%map->slots_count;
for(E_String2ExprMapNode *node = map->slots[slot_idx].first;
node != 0;
@@ -223,7 +223,7 @@ e_string2expr_map_inc_poison(E_String2ExprMap *map, String8 string)
internal void
e_string2expr_map_dec_poison(E_String2ExprMap *map, String8 string)
{
U64 hash = e_hash_from_string(string);
U64 hash = e_hash_from_string(5381, string);
U64 slot_idx = hash%map->slots_count;
for(E_String2ExprMapNode *node = map->slots[slot_idx].first;
node != 0;
@@ -243,7 +243,7 @@ e_expr_from_string(E_String2ExprMap *map, String8 string)
E_Expr *expr = &e_expr_nil;
if(map->slots_count != 0)
{
U64 hash = e_hash_from_string(string);
U64 hash = e_hash_from_string(5381, string);
U64 slot_idx = hash%map->slots_count;
E_String2ExprMapNode *existing_node = 0;
for(E_String2ExprMapNode *node = map->slots[slot_idx].first; node != 0; node = node->hash_next)
@@ -844,13 +844,13 @@ e_type_from_expr(E_Expr *expr)
case E_ExprKind_Ptr:
{
E_TypeKey direct_type_key = e_type_from_expr(expr->first);
result = e_type_key_cons(E_TypeKind_Ptr, direct_type_key, 0);
result = e_type_key_cons_ptr(direct_type_key);
}break;
case E_ExprKind_Array:
{
E_Expr *child_expr = expr->first;
E_TypeKey direct_type_key = e_type_from_expr(child_expr);
result = e_type_key_cons(E_TypeKind_Array, direct_type_key, expr->u64);
result = e_type_key_cons_array(direct_type_key, expr->u64);
}break;
}
return result;
@@ -1131,7 +1131,7 @@ e_parse_expr_from_text_tokens__prec(Arena *arena, String8 text, E_TokenArray *to
// rjf: build cast-to-U64*, and dereference operators
E_Expr *type = e_push_expr(arena, E_ExprKind_TypeIdent, token_string.str);
type->type_key = e_type_key_cons(E_TypeKind_Ptr, e_type_key_basic(E_TypeKind_U64), 0);
type->type_key = e_type_key_cons_ptr(e_type_key_basic(E_TypeKind_U64));
E_Expr *casted = atom;
E_Expr *cast = e_push_expr(arena, E_ExprKind_Cast, token_string.str);
e_expr_push_child(cast, type);
+1 -1
View File
@@ -231,7 +231,7 @@ thread_static E_ParseCtx *e_parse_ctx = 0;
////////////////////////////////
//~ rjf: Basic Helper Functions
internal U64 e_hash_from_string(String8 string);
internal U64 e_hash_from_string(U64 seed, String8 string);
////////////////////////////////
//~ rjf: Basic Map Functions
+137 -29
View File
@@ -237,28 +237,72 @@ e_type_key_reg_alias(Architecture arch, REGS_AliasCode code)
return key;
}
internal E_TypeKey
e_type_key_cons(E_TypeKind kind, E_TypeKey direct_key, U64 u64)
//- rjf: constructed type construction
internal U64
e_hash_from_cons_type_params(E_ConsTypeParams *params)
{
U32 buffer[] =
{
(U32)kind,
(U32)direct_key.kind,
(U32)direct_key.u32[0],
(U32)direct_key.u32[1],
(U32)direct_key.u32[2],
(U32)((u64 & 0x00000000ffffffffull)>> 0),
(U32)((u64 & 0xffffffff00000000ull)>> 32),
(U32)params->kind,
(U32)params->direct_key.kind,
params->direct_key.u32[0],
params->direct_key.u32[1],
params->direct_key.u32[2],
(U32)((params->count & 0x00000000ffffffffull)>> 0),
(U32)((params->count & 0xffffffff00000000ull)>> 32),
};
U64 content_hash = e_hash_from_string(str8((U8 *)buffer, sizeof(buffer)));
U64 hash = e_hash_from_string(5381, str8((U8 *)buffer, sizeof(buffer)));
hash = e_hash_from_string(hash, params->name);
return hash;
}
internal B32
e_cons_type_params_match(E_ConsTypeParams *l, E_ConsTypeParams *r)
{
B32 result = (l->kind == r->kind &&
str8_match(l->name, r->name, 0) &&
e_type_key_match(l->direct_key, r->direct_key) &&
l->count == r->count);
if(result && l->members != 0 && r->members != 0)
{
for(U64 idx = 0; idx < l->count; idx += 1)
{
if(l->members[idx].kind != r->members[idx].kind ||
!e_type_key_match(l->members[idx].type_key, r->members[idx].type_key) ||
!str8_match(l->members[idx].name, r->members[idx].name, 0) ||
l->members[idx].off != r->members[idx].off)
{
result = 0;
break;
}
}
}
if(result && l->enum_vals != 0 && r->enum_vals != 0)
{
for(U64 idx = 0; idx < l->count; idx += 1)
{
if(l->enum_vals[idx].val != r->enum_vals[idx].val ||
!str8_match(l->enum_vals[idx].name, r->enum_vals[idx].name, 0))
{
result = 0;
break;
}
}
}
return result;
}
internal E_TypeKey
e_type_key_cons_(E_ConsTypeParams *params)
{
U64 content_hash = e_hash_from_cons_type_params(params);
U64 content_slot_idx = content_hash%e_type_state->cons_content_slots_count;
E_ConsTypeSlot *content_slot = &e_type_state->cons_content_slots[content_slot_idx];
E_ConsTypeNode *node = 0;
for(E_ConsTypeNode *n = content_slot->first; n != 0; n = n->content_next)
{
if(e_type_kind_from_key(n->key) == kind &&
e_type_key_match(n->direct_key, direct_key) &&
n->u64 == u64)
if(e_cons_type_params_match(params, &n->params))
{
node = n;
break;
@@ -268,18 +312,37 @@ e_type_key_cons(E_TypeKind kind, E_TypeKey direct_key, U64 u64)
if(node == 0)
{
E_TypeKey key = {E_TypeKeyKind_Cons};
key.u32[0] = (U32)kind;
key.u32[0] = (U32)params->kind;
key.u32[1] = (U32)e_type_state->cons_id_gen;
e_type_state->cons_id_gen += 1;
U64 key_hash = e_hash_from_string(str8_struct(&key));
U64 key_hash = e_hash_from_string(5381, str8_struct(&key));
U64 key_slot_idx = key_hash%e_type_state->cons_key_slots_count;
E_ConsTypeSlot *key_slot = &e_type_state->cons_key_slots[key_slot_idx];
E_ConsTypeNode *node = push_array(e_type_state->arena, E_ConsTypeNode, 1);
SLLQueuePush_N(content_slot->first, content_slot->last, node, content_next);
SLLQueuePush_N(key_slot->first, key_slot->last, node, key_next);
node->key = key;
node->direct_key = direct_key;
node->u64 = u64;
MemoryCopyStruct(&node->params, params);
node->params.name = push_str8_copy(e_type_state->arena, params->name);
if(params->members != 0)
{
node->params.members = push_array(e_type_state->arena, E_Member, params->count);
MemoryCopy(node->params.members, params->members, sizeof(E_Member)*params->count);
for(U64 idx = 0; idx < node->params.count; idx += 1)
{
node->params.members[idx].name = push_str8_copy(e_type_state->arena, node->params.members[idx].name);
node->params.members[idx].inheritance_key_chain = e_type_key_list_copy(e_type_state->arena, &node->params.members[idx].inheritance_key_chain);
}
}
else if(params->enum_vals != 0)
{
node->params.enum_vals = push_array(e_type_state->arena, E_EnumVal, params->count);
MemoryCopy(node->params.enum_vals, params->enum_vals, sizeof(E_EnumVal)*params->count);
for(U64 idx = 0; idx < node->params.count; idx += 1)
{
node->params.enum_vals[idx].name = push_str8_copy(e_type_state->arena, node->params.enum_vals[idx].name);
}
}
result = key;
}
else
@@ -289,6 +352,22 @@ e_type_key_cons(E_TypeKind kind, E_TypeKey direct_key, U64 u64)
return result;
}
//- rjf: constructed type helpers
internal E_TypeKey
e_type_key_cons_array(E_TypeKey element_type_key, U64 count)
{
E_TypeKey key = e_type_key_cons(.kind = E_TypeKind_Array, .direct_key = element_type_key, .count = count);
return key;
}
internal E_TypeKey
e_type_key_cons_ptr(E_TypeKey element_type_key)
{
E_TypeKey key = e_type_key_cons(.kind = E_TypeKind_Ptr, .direct_key = element_type_key);
return key;
}
//- rjf: basic type key functions
internal B32
@@ -342,7 +421,7 @@ e_type_from_key(Arena *arena, E_TypeKey key)
//- rjf: constructed type keys
case E_TypeKeyKind_Cons:
{
U64 key_hash = e_hash_from_string(str8_struct(&key));
U64 key_hash = e_hash_from_string(5381, str8_struct(&key));
U64 key_slot_idx = key_hash%e_type_state->cons_key_slots_count;
E_ConsTypeSlot *key_slot = &e_type_state->cons_key_slots[key_slot_idx];
for(E_ConsTypeNode *node = key_slot->first;
@@ -353,19 +432,48 @@ e_type_from_key(Arena *arena, E_TypeKey key)
{
type = push_array(arena, E_Type, 1);
type->kind = e_type_kind_from_key(node->key);
type->direct_type_key = node->direct_key;
type->count = node->u64;
type->name = push_str8_copy(arena, node->params.name);
type->direct_type_key = node->params.direct_key;
type->count = node->params.count;
switch(type->kind)
{
default:
{
type->byte_size = e_type_byte_size_from_key(type->direct_type_key);
}break;
case E_TypeKind_Ptr:
{
type->byte_size = bit_size_from_arch(e_type_state->ctx->arch)/8;
}break;
case E_TypeKind_Array:
{
U64 ptee_size = e_type_byte_size_from_key(node->direct_key);
U64 ptee_size = e_type_byte_size_from_key(node->params.direct_key);
type->byte_size = ptee_size * type->count;
}break;
case E_TypeKind_Struct:
{
type->members = push_array(arena, E_Member, type->count);
MemoryCopy(type->members, node->params.members, sizeof(E_Member)*type->count);
for(U64 idx = 0; idx < type->count; idx += 1)
{
type->byte_size += e_type_byte_size_from_key(type->members[idx].type_key);
}
}break;
case E_TypeKind_Union:
{
type->members = push_array(arena, E_Member, type->count);
MemoryCopy(type->members, node->params.members, sizeof(E_Member)*type->count);
for(U64 idx = 0; idx < type->count; idx += 1)
{
U64 member_size = e_type_byte_size_from_key(type->members[idx].type_key);
type->byte_size = Max(type->byte_size, member_size);
}
}break;
case E_TypeKind_Enum:
{
type->enum_vals = push_array(arena, E_EnumVal, type->count);
MemoryCopy(type->enum_vals, node->params.enum_vals, sizeof(E_EnumVal)*type->count);
}break;
}
}
}
@@ -768,7 +876,7 @@ e_type_from_key(Arena *arena, E_TypeKey key)
E_Member *mem = &n->v;
mem->kind = E_MemberKind_DataField;
mem->name = str8_lit("u128s");
mem->type_key = e_type_key_cons(E_TypeKind_Array, e_type_key_basic(E_TypeKind_U128), reg_byte_count/16);
mem->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U128), reg_byte_count/16);
}
if(type->byte_size > 8 && type->byte_size%8 == 0)
{
@@ -778,7 +886,7 @@ e_type_from_key(Arena *arena, E_TypeKey key)
E_Member *mem = &n->v;
mem->kind = E_MemberKind_DataField;
mem->name = str8_lit("u64s");
mem->type_key = e_type_key_cons(E_TypeKind_Array, e_type_key_basic(E_TypeKind_U64), reg_byte_count/8);
mem->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U64), reg_byte_count/8);
}
if(type->byte_size > 4 && type->byte_size%4 == 0)
{
@@ -788,7 +896,7 @@ e_type_from_key(Arena *arena, E_TypeKey key)
E_Member *mem = &n->v;
mem->kind = E_MemberKind_DataField;
mem->name = str8_lit("u32s");
mem->type_key = e_type_key_cons(E_TypeKind_Array, e_type_key_basic(E_TypeKind_U32), reg_byte_count/4);
mem->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U32), reg_byte_count/4);
}
if(type->byte_size > 2 && type->byte_size%2 == 0)
{
@@ -798,7 +906,7 @@ e_type_from_key(Arena *arena, E_TypeKey key)
E_Member *mem = &n->v;
mem->kind = E_MemberKind_DataField;
mem->name = str8_lit("u16s");
mem->type_key = e_type_key_cons(E_TypeKind_Array, e_type_key_basic(E_TypeKind_U16), reg_byte_count/2);
mem->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U16), reg_byte_count/2);
}
if(type->byte_size > 1)
{
@@ -808,7 +916,7 @@ e_type_from_key(Arena *arena, E_TypeKey key)
E_Member *mem = &n->v;
mem->kind = E_MemberKind_DataField;
mem->name = str8_lit("u8s");
mem->type_key = e_type_key_cons(E_TypeKind_Array, e_type_key_basic(E_TypeKind_U8), reg_byte_count);
mem->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), reg_byte_count);
}
if(type->byte_size > 4 && type->byte_size%4 == 0)
{
@@ -818,7 +926,7 @@ e_type_from_key(Arena *arena, E_TypeKey key)
E_Member *mem = &n->v;
mem->kind = E_MemberKind_DataField;
mem->name = str8_lit("f32s");
mem->type_key = e_type_key_cons(E_TypeKind_Array, e_type_key_basic(E_TypeKind_F32), reg_byte_count/4);
mem->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_F32), reg_byte_count/4);
}
if(type->byte_size > 8 && type->byte_size%8 == 0)
{
@@ -828,7 +936,7 @@ e_type_from_key(Arena *arena, E_TypeKey key)
E_Member *mem = &n->v;
mem->kind = E_MemberKind_DataField;
mem->name = str8_lit("f64s");
mem->type_key = e_type_key_cons(E_TypeKind_Array, e_type_key_basic(E_TypeKind_F64), reg_byte_count/8);
mem->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_F64), reg_byte_count/8);
}
}
}
@@ -1267,7 +1375,7 @@ e_type_data_members_from_key(Arena *arena, E_TypeKey key)
E_Member *padding_member = &new_members.v[n->prev_member_idx+padding_idx+1];
MemoryZeroStruct(padding_member);
padding_member->kind = E_MemberKind_Padding;
padding_member->type_key = e_type_key_cons(E_TypeKind_Array, e_type_key_basic(E_TypeKind_U8), n->size);
padding_member->type_key = e_type_key_cons_array(e_type_key_basic(E_TypeKind_U8), n->size);
padding_member->off = n->off;
padding_member->name = str8_lit("padding");
padding_idx += 1;
+26 -7
View File
@@ -24,8 +24,8 @@ struct E_TypeKey
E_TypeKeyKind kind;
U32 u32[3];
// [0] -> E_TypeKind (Basic, Cons, Ext); Architecture (Reg, RegAlias)
// [1] -> Type Index In RDI (Cons, Ext); Code (Reg, RegAlias)
// [2] -> RDI Index (Cons, Ext)
// [1] -> Type Index In RDI (Ext); Code (Reg, RegAlias); Type Index In Constructed (Cons)
// [2] -> RDI Index (Ext)
};
typedef struct E_TypeKeyNode E_TypeKeyNode;
@@ -135,14 +135,24 @@ struct E_Type
////////////////////////////////
//~ rjf: Evaluation Context
typedef struct E_ConsTypeNode E_ConsTypeNode;
typedef struct E_ConsTypeParams E_ConsTypeParams;
struct E_ConsTypeParams
{
E_TypeKind kind;
String8 name;
E_TypeKey direct_key;
U64 count;
E_Member *members;
E_EnumVal *enum_vals;
};
typedef struct E_ConsTypeNode E_ConsTypeNode;
struct E_ConsTypeNode
{
E_ConsTypeNode *key_next;
E_ConsTypeNode *content_next;
E_TypeKey key;
E_TypeKey direct_key;
U64 u64;
E_ConsTypeParams params;
};
typedef struct E_ConsTypeSlot E_ConsTypeSlot;
@@ -211,13 +221,22 @@ internal void e_select_type_ctx(E_TypeCtx *ctx);
////////////////////////////////
//~ rjf: Type Operation Functions
//- rjf: key constructors
//- rjf: basic key constructors
internal E_TypeKey e_type_key_zero(void);
internal E_TypeKey e_type_key_basic(E_TypeKind kind);
internal E_TypeKey e_type_key_ext(E_TypeKind kind, U32 type_idx, U32 rdi_idx);
internal E_TypeKey e_type_key_reg(Architecture arch, REGS_RegCode code);
internal E_TypeKey e_type_key_reg_alias(Architecture arch, REGS_AliasCode code);
internal E_TypeKey e_type_key_cons(E_TypeKind kind, E_TypeKey direct_key, U64 u64);
//- rjf: constructed type construction
internal U64 e_hash_from_cons_type_params(E_ConsTypeParams *params);
internal B32 e_cons_type_params_match(E_ConsTypeParams *l, E_ConsTypeParams *r);
internal E_TypeKey e_type_key_cons_(E_ConsTypeParams *params);
#define e_type_key_cons(...) e_type_key_cons_(&(E_ConsTypeParams){.kind = E_TypeKind_Null, __VA_ARGS__})
//- rjf: constructed type construction helpers
internal E_TypeKey e_type_key_cons_array(E_TypeKey element_type_key, U64 count);
internal E_TypeKey e_type_key_cons_ptr(E_TypeKey element_type_key);
//- rjf: basic type key functions
internal B32 e_type_key_match(E_TypeKey l, E_TypeKey r);