From c1b34617095a06305ee07416fce88e73acf21bf7 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Thu, 25 Jun 2026 11:36:18 -0600 Subject: [PATCH] eval2: switch to extrusive lists for expression lists - this lets us reuse expression trees. also solve strange isolated unload module events in win32 demon as well --- src/eval2/eval2.c | 62 +++++++++++++++++++---------------- src/eval2/eval2.h | 35 +++++++++++++------- src/scratch/ryan_scratch.c | 1 + src/win32/demon/win32_demon.c | 5 ++- 4 files changed, 62 insertions(+), 41 deletions(-) diff --git a/src/eval2/eval2.c b/src/eval2/eval2.c index 80f1392e..287b98c7 100644 --- a/src/eval2/eval2.c +++ b/src/eval2/eval2.c @@ -799,7 +799,7 @@ e2_expr_unary_op(Arena *arena, E2_TypeKey type_key, RDI_EvalOp op, E2_Expr *oper e->mode = E2_Mode_Value; e->val.u512.u8[0] = e2_type_group_from_kind(e2_type_kind_from_key(type_key)); e->val.u512.u8[1] = 8*e2_byte_size_from_type_key(type_key); - e2_expr_push_child(e, operand); + e2_expr_push_child(arena, e, operand); return e; } @@ -817,8 +817,8 @@ e2_expr_binary_op(Arena *arena, E2_TypeKey type_key, RDI_EvalOp op, E2_Expr *lhs e->mode = E2_Mode_Value; e->val.u512.u8[0] = e2_type_group_from_kind(e2_type_kind_from_key(arith_type_key)); e->val.u512.u8[1] = 8*e2_byte_size_from_type_key(arith_type_key); - e2_expr_push_child(e, lhs); - e2_expr_push_child(e, rhs); + e2_expr_push_child(arena, e, lhs); + e2_expr_push_child(arena, e, rhs); return e; } @@ -833,7 +833,7 @@ e2_expr_resolve_to_value(Arena *arena, E2_Expr *expr) result = e2_expr(arena); result->type_key = e2_type_key_direct(e2_type_key_undecorate(expr->type_key)); result->mode = E2_Mode_Value; - e2_expr_push_child(result, expr); + e2_expr_push_child(arena, result, expr); } // rjf: address evaluations -> read value from space @@ -846,7 +846,7 @@ e2_expr_resolve_to_value(Arena *arena, E2_Expr *expr) memread_expr->mode = E2_Mode_Value; memread_expr->type_key = expr->type_key; memread_expr->val.u64 = memread_byte_size; - e2_expr_push_child(memread_expr, expr); + e2_expr_push_child(arena, memread_expr, expr); result = memread_expr; } @@ -885,7 +885,7 @@ e2_expr_truncate(Arena *arena, E2_Expr *expr, E2_TypeKey dst_type_key) result->type_key = dst_type_key; result->op = dst_type_is_signed ? RDI_EvalOp_TruncSigned : RDI_EvalOp_Trunc; result->val.u64 = dst_type_byte_size*8; - e2_expr_push_child(result, expr); + e2_expr_push_child(arena, result, expr); } return result; } @@ -913,7 +913,7 @@ e2_expr_convert_if_possible(Arena *arena, E2_Expr *expr, E2_TypeKey dst_type_key result->type_key = dst_type_key; result->op = RDI_EvalOp_Convert; result->val.u64 = src_type_group | (dst_type_group << 8); - e2_expr_push_child(result, expr); + e2_expr_push_child(arena, result, expr); } // rjf: no-op from src -> dst @@ -941,12 +941,20 @@ e2_expr_type(Arena *arena, E2_TypeKey type_key) } internal void -e2_expr_push_child(E2_Expr *parent, E2_Expr *expr) +e2_expr_push_child_node(E2_Expr *parent, E2_ExprNode *node) { - SLLQueuePush_NZ(&e2_expr_nil, parent->first, parent->last, expr, next); + SLLQueuePush(parent->first_child, parent->last_child, node); parent->child_count += 1; } +internal void +e2_expr_push_child(Arena *arena, E2_Expr *parent, E2_Expr *expr) +{ + E2_ExprNode *n = push_array(arena, E2_ExprNode, 1); + n->v = expr; + e2_expr_push_child_node(parent, n); +} + //////////////////////////////// //~ rjf: String -> Expression @@ -1626,10 +1634,9 @@ e2_parse_from_string(Arena *arena, E2_ParseState *state, E2_ExprMap *expr_map, E if(lhs != rhs) { finished_root = e2_expr(arena); - for EachNode(n, E2_ExprNode, completed_task->first_child) - { - e2_expr_push_child(finished_root, n->v); - } + finished_root->first_child = completed_task->first_child; + finished_root->last_child = completed_task->last_child; + finished_root->child_count = completed_task->child_count; } else { @@ -1712,10 +1719,9 @@ e2_parse_from_string(Arena *arena, E2_ParseState *state, E2_ExprMap *expr_map, E else { E2_Expr *params_expr = e2_expr(arena); - for(E2_ExprNode *n = completed_task->first_child->next; n != 0; n = n->next) - { - e2_expr_push_child(params_expr, n->v); - } + params_expr->first_child = completed_task->first_child->next; + params_expr->last_child = completed_task->last_child; + params_expr->child_count = completed_task->child_count-1; done = 1; parse.status = E2_ParseStatus_Call; parse.expr = lhs; @@ -2152,11 +2158,11 @@ e2_parse_from_string(Arena *arena, E2_ParseState *state, E2_ExprMap *expr_map, E E2_Expr *cond_root = e2_expr(arena); E2_Expr *cjump_expr = e2_expr(arena); E2_Expr *jump_expr = e2_expr(arena); - e2_expr_push_child(cond_root, condition_expr); - e2_expr_push_child(cond_root, cjump_expr); - e2_expr_push_child(cond_root, fail_expr); - e2_expr_push_child(cond_root, jump_expr); - e2_expr_push_child(cond_root, pass_expr); + e2_expr_push_child(arena, cond_root, condition_expr); + e2_expr_push_child(arena, cond_root, cjump_expr); + e2_expr_push_child(arena, cond_root, fail_expr); + e2_expr_push_child(arena, cond_root, jump_expr); + e2_expr_push_child(arena, cond_root, pass_expr); // rjf: compute # of bytes for pass U64 pass_expr_byte_count = 0; @@ -2318,10 +2324,10 @@ e2_bytecode_from_expr(Arena *arena, E2_Expr *expr) { Task *next; E2_Expr *e; - E2_Expr *last_pushed_child; + E2_ExprNode *last_pushed_child_node; U64 pushed_child_count; }; - Task start_task = {0, expr, &e2_expr_nil}; + Task start_task = {0, expr}; Task *top_task = &start_task; Task *free_task = 0; for(Task *t = top_task; t != 0; t = top_task) @@ -2340,7 +2346,7 @@ e2_bytecode_from_expr(Arena *arena, E2_Expr *expr) if(t->pushed_child_count < child_count) { t->pushed_child_count += 1; - E2_Expr *next_child = (t->last_pushed_child == &e2_expr_nil ? e->first : t->last_pushed_child->next); + E2_ExprNode *next_child_node = (t->last_pushed_child_node == 0 ? e->first_child : t->last_pushed_child_node->next); Task *child_task = free_task; if(child_task != 0) { @@ -2352,10 +2358,10 @@ e2_bytecode_from_expr(Arena *arena, E2_Expr *expr) } MemoryZeroStruct(child_task); SLLStackPush(top_task, child_task); - child_task->e = next_child; - child_task->last_pushed_child = &e2_expr_nil; + child_task->e = next_child_node ? next_child_node->v : &e2_expr_nil; + child_task->last_pushed_child_node = 0; child_task->pushed_child_count = 0; - t->last_pushed_child = next_child; + t->last_pushed_child_node = next_child_node; } //- rjf: did push of all children -> push this expr's op, pop off stack diff --git a/src/eval2/eval2.h b/src/eval2/eval2.h index a1c7ee21..46723de3 100644 --- a/src/eval2/eval2.h +++ b/src/eval2/eval2.h @@ -166,6 +166,16 @@ struct E2_ConsTypeSlot E2_ConsTypeNode *last; }; +typedef struct E2_ConsTypeMap E2_ConsTypeMap; +struct E2_ConsTypeMap +{ + U64 id_gen; + U64 content_slots_count; + E2_ConsTypeSlot *content_slots; + U64 key_slots_count; + E2_ConsTypeSlot *key_slots; +}; + //////////////////////////////// //~ rjf: Evaluation Values @@ -279,12 +289,18 @@ struct E2_Token //////////////////////////////// //~ rjf: Expression Tree Building +typedef struct E2_ExprNode E2_ExprNode; +struct E2_ExprNode +{ + E2_ExprNode *next; + struct E2_Expr *v; +}; + typedef struct E2_Expr E2_Expr; struct E2_Expr { - E2_Expr *first; - E2_Expr *last; - E2_Expr *next; + E2_ExprNode *first_child; + E2_ExprNode *last_child; U64 child_count; Rng1U64 src_range; String8 string; @@ -294,13 +310,6 @@ struct E2_Expr E2_Val val; }; -typedef struct E2_ExprNode E2_ExprNode; -struct E2_ExprNode -{ - E2_ExprNode *next; - E2_Expr *v; -}; - typedef struct E2_ExprMapNode E2_ExprMapNode; struct E2_ExprMapNode { @@ -424,8 +433,9 @@ struct E2_Interp //~ rjf: Globals thread_static E2_Assets *e2_assets = 0; +read_only global E2_ConsTypeNode e2_cons_type_node_nil = {&e2_cons_type_node_nil, &e2_cons_type_node_nil}; read_only global E2_DbgInfo e2_dbg_info_nil = {{0}, &rdi_parsed_nil}; -read_only global E2_Expr e2_expr_nil = {&e2_expr_nil, &e2_expr_nil, &e2_expr_nil}; +read_only global E2_Expr e2_expr_nil = {0}; //////////////////////////////// //~ rjf: Space -> Memory Map Helpers @@ -530,7 +540,8 @@ internal E2_Expr *e2_expr_resolve_to_value(Arena *arena, E2_Expr *expr); internal E2_Expr *e2_expr_truncate(Arena *arena, E2_Expr *expr, E2_TypeKey dst_type_key); internal E2_Expr *e2_expr_convert_if_possible(Arena *arena, E2_Expr *expr, E2_TypeKey dst_type_key); internal E2_Expr *e2_expr_type(Arena *arena, E2_TypeKey type_key); -internal void e2_expr_push_child(E2_Expr *parent, E2_Expr *expr); +internal void e2_expr_push_child_node(E2_Expr *parent, E2_ExprNode *node); +internal void e2_expr_push_child(Arena *arena, E2_Expr *parent, E2_Expr *expr); //////////////////////////////// //~ rjf: String -> Expression diff --git a/src/scratch/ryan_scratch.c b/src/scratch/ryan_scratch.c index bf85cd64..00f10e92 100644 --- a/src/scratch/ryan_scratch.c +++ b/src/scratch/ryan_scratch.c @@ -41,6 +41,7 @@ entry_point(CmdLine *cmdline) // (A) // int & B // (1 + (int)&B) + s("123, 456"), s("int32 == int32"), s("foo = 123"), s("1 > 2"), diff --git a/src/win32/demon/win32_demon.c b/src/win32/demon/win32_demon.c index f8c9f6cf..3144f426 100644 --- a/src/win32/demon/win32_demon.c +++ b/src/win32/demon/win32_demon.c @@ -2359,7 +2359,10 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls) W32_DMN_Entity *module = w32_dmn_entity_from_kind_id(W32_DMN_EntityKind_Module, module_base); W32_DMN_Entity *process = module->parent; - // rjf: generate event + // rjf: generate event, if this is a valid module (in some niche scenarios - + // potentially related to antivirus - spurious unload dll events are generated + // for modules we've never seen before!) + if(module != &w32_dmn_entity_nil) { DMN_Event *e = dmn_event_list_push(arena, &events); e->kind = DMN_EventKind_UnloadModule;