diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 914d1ea6..a8bb074b 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -217,6 +217,16 @@ ctrl_handle_from_string(String8 string) return handle; } +internal E_Eval +ctrl_eval_from_handle(CTRL_Handle handle) +{ + Temp scratch = scratch_begin(0, 0); + String8 string = ctrl_string_from_handle(scratch.arena, handle); + E_Eval eval = e_eval_from_string(string); + scratch_end(scratch); + return eval; +} + //////////////////////////////// //~ rjf: Trap Type Functions @@ -1412,6 +1422,7 @@ ctrl_init(void) scratch_end(scratch); } ctrl_state->ctrl_thread_entity_store = ctrl_entity_store_alloc(); + ctrl_state->ctrl_thread_eval_cache = e_cache_alloc(); ctrl_state->dmn_event_arena = arena_alloc(); ctrl_state->user_entry_point_arena = arena_alloc(); ctrl_state->dbg_dir_arena = arena_alloc(); @@ -4754,6 +4765,11 @@ ctrl_thread__eval_scope_begin(Arena *arena, CTRL_Entity *thread) } } + ////////////////////////////// + //- rjf: select evaluation cache + // + e_select_cache(ctrl_state->ctrl_thread_eval_cache); + ////////////////////////////// //- rjf: build base evaluation context // @@ -4778,12 +4794,6 @@ ctrl_thread__eval_scope_begin(Arena *arena, CTRL_Entity *thread) } e_select_base_ctx(&scope->base_ctx); - ////////////////////////////// - //- rjf: begin type evaluation - // - e_parse_eval_begin(); - e_type_eval_begin(); - ////////////////////////////// //- rjf: build IR evaluation context // @@ -4819,11 +4829,6 @@ ctrl_thread__eval_scope_begin(Arena *arena, CTRL_Entity *thread) } e_select_interpret_ctx(&scope->interpret_ctx, eval_modules_primary->rdi, thread_rip_voff); - //////////////////////////// - //- rjf: begin cached evaluations - // - e_cache_eval_begin(); - return scope; } @@ -5886,7 +5891,7 @@ ctrl_thread__run(DMN_CtrlCtx *ctrl_ctx, CTRL_Msg *msg) E_Eval eval = zero_struct; ProfScope("evaluate expression") { - eval = e_eval_from_string(temp.arena, condition_n->string); + eval = e_eval_from_string(condition_n->string); } // rjf: interpret evaluation diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index f5127226..84af61bb 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -709,6 +709,7 @@ struct CTRL_State OS_Handle ctrl_thread; Log *ctrl_thread_log; CTRL_EntityStore *ctrl_thread_entity_store; + E_Cache *ctrl_thread_eval_cache; Arena *dmn_event_arena; DMN_EventNode *first_dmn_event_node; DMN_EventNode *last_dmn_event_node; @@ -769,6 +770,8 @@ internal B32 ctrl_handle_match(CTRL_Handle a, CTRL_Handle b); internal void ctrl_handle_list_push(Arena *arena, CTRL_HandleList *list, CTRL_Handle *pair); internal CTRL_HandleList ctrl_handle_list_copy(Arena *arena, CTRL_HandleList *src); internal String8 ctrl_string_from_handle(Arena *arena, CTRL_Handle handle); +internal CTRL_Handle ctrl_handle_from_string(String8 string); +internal E_Eval ctrl_eval_from_handle(CTRL_Handle handle); //////////////////////////////// //~ rjf: Trap Type Functions diff --git a/src/eval/eval_bundles.c b/src/eval/eval_bundles.c index 98ca8c89..b05ea40c 100644 --- a/src/eval/eval_bundles.c +++ b/src/eval/eval_bundles.c @@ -4,6 +4,7 @@ //////////////////////////////// //~ rjf: Bundled Evaluation Functions +#if 0 internal E_Eval e_eval_from_expr(Arena *arena, E_Expr *expr) { @@ -144,63 +145,6 @@ e_dynamically_typed_eval_from_eval(E_Eval eval) return eval; } -internal E_Eval -e_value_eval_from_eval(E_Eval eval) -{ - ProfBeginFunction(); - if(eval.irtree.mode == E_Mode_Offset) - { - E_TypeKey type_key = e_type_key_unwrap(eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative); - E_TypeKind type_kind = e_type_kind_from_key(type_key); - if(type_kind == E_TypeKind_Array) - { - eval.irtree.mode = E_Mode_Value; - } - else - { - U64 type_byte_size = e_type_byte_size_from_key(type_key); - Rng1U64 value_vaddr_range = r1u64(eval.value.u64, eval.value.u64 + type_byte_size); - MemoryZeroStruct(&eval.value); - if(!e_type_key_match(type_key, e_type_key_zero()) && - type_byte_size <= sizeof(E_Value) && - e_space_read(eval.space, &eval.value, value_vaddr_range)) - { - eval.irtree.mode = E_Mode_Value; - - // rjf: mask&shift, for bitfields - if(type_kind == E_TypeKind_Bitfield && type_byte_size <= sizeof(U64)) - { - Temp scratch = scratch_begin(0, 0); - E_Type *type = e_type_from_key__cached(type_key); - U64 valid_bits_mask = 0; - for(U64 idx = 0; idx < type->count; idx += 1) - { - valid_bits_mask |= (1ull<> type->off; - eval.value.u64 = eval.value.u64 & valid_bits_mask; - eval.irtree.type_key = type->direct_type_key; - scratch_end(scratch); - } - - // rjf: manually sign-extend - switch(type_kind) - { - default: break; - case E_TypeKind_Char8: - case E_TypeKind_S8: {eval.value.s64 = (S64)*((S8 *)&eval.value.u64);}break; - case E_TypeKind_Char16: - case E_TypeKind_S16: {eval.value.s64 = (S64)*((S16 *)&eval.value.u64);}break; - case E_TypeKind_Char32: - case E_TypeKind_S32: {eval.value.s64 = (S64)*((S32 *)&eval.value.u64);}break; - } - } - } - } - ProfEnd(); - return eval; -} - internal E_Value e_value_from_string(String8 string) { @@ -267,6 +211,8 @@ e_eval_wrapf(Arena *arena, E_Eval eval, char *fmt, ...) return result; } +#endif + internal U64 e_base_offset_from_eval(E_Eval eval) { @@ -389,7 +335,7 @@ e_debug_log_from_expr_string(Arena *arena, String8 string) } //- rjf: type - E_IRTreeAndType irtree = e_push_irtree_and_type_from_expr(scratch.arena, parse.expr); + E_IRTreeAndType irtree = e_push_irtree_and_type_from_expr(scratch.arena, 0, 0, 0, parse.expr); { str8_list_pushf(scratch.arena, &strings, " type:\n"); S32 indent = 2; diff --git a/src/eval/eval_bundles.h b/src/eval/eval_bundles.h index f56457b1..3d271963 100644 --- a/src/eval/eval_bundles.h +++ b/src/eval/eval_bundles.h @@ -7,6 +7,7 @@ //////////////////////////////// //~ rjf: Bundled Evaluation Functions +#if 0 internal E_Eval e_eval_from_expr(Arena *arena, E_Expr *expr); internal E_Eval e_eval_from_string(Arena *arena, String8 string); internal E_Eval e_eval_from_stringf(Arena *arena, char *fmt, ...); @@ -18,6 +19,7 @@ internal E_Value e_value_from_expr(E_Expr *expr); internal E_Value e_value_from_eval(E_Eval eval); internal E_Eval e_eval_wrap(Arena *arena, E_Eval eval, String8 string); internal E_Eval e_eval_wrapf(Arena *arena, E_Eval eval, char *fmt, ...);; +#endif internal U64 e_base_offset_from_eval(E_Eval eval); internal Rng1U64 e_range_from_eval(E_Eval eval); diff --git a/src/eval/eval_cache.c b/src/eval/eval_cache.c deleted file mode 100644 index c171c647..00000000 --- a/src/eval/eval_cache.c +++ /dev/null @@ -1,256 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -//////////////////////////////// -//~ rjf: Basic Key Helpers - -internal B32 -e_key_match(E_Key a, E_Key b) -{ - B32 result = (a.u64 == b.u64); - return result; -} - -//////////////////////////////// -//~ rjf: Cache Initialization (Required For All Subsequent APIs) - -internal void -e_cache_eval_begin(void) -{ - if(e_cache == 0) - { - Arena *arena = arena_alloc(); - e_cache = push_array(arena, E_Cache, 1); - e_cache->arena = arena; - e_cache->arena_eval_start_pos = arena_pos(arena); - } - arena_pop_to(e_cache->arena, e_cache->arena_eval_start_pos); - e_cache->key_id_gen = 0; - e_cache->key_slots_count = 4096; - e_cache->key_slots = push_array(e_cache->arena, E_CacheSlot, e_cache->key_slots_count); - e_cache->string_slots_count = 4096; - e_cache->string_slots = push_array(e_cache->arena, E_CacheSlot, e_cache->string_slots_count); - e_cache->free_parent_node = 0; - e_cache->top_parent_node = 0; -} - -//////////////////////////////// -//~ rjf: Cache Accessing Functions - -//- rjf: parent key stack - -internal E_Key -e_parent_key_push(E_Key key) -{ - E_Key top = {0}; - if(e_cache->top_parent_node != 0) - { - top = e_cache->top_parent_node->key; - } - E_CacheParentNode *n = e_cache->free_parent_node; - if(n != 0) - { - SLLStackPop(e_cache->free_parent_node); - } - else - { - n = push_array(e_cache->arena, E_CacheParentNode, 1); - } - SLLStackPush(e_cache->top_parent_node, n); - n->key = key; - return top; -} - -internal E_Key -e_parent_key_pop(void) -{ - E_CacheParentNode *n = e_cache->top_parent_node; - SLLStackPop(e_cache->top_parent_node); - SLLStackPush(e_cache->free_parent_node, n); - E_Key popped = n->key; - return popped; -} - -//- rjf: key construction - -internal E_Key -e_key_from_string(String8 string) -{ - E_Key parent_key = {0}; - if(e_cache->top_parent_node) - { - parent_key = e_cache->top_parent_node->key; - } - U64 hash = e_hash_from_string(parent_key.u64, string); - U64 slot_idx = hash%e_cache->string_slots_count; - E_CacheSlot *slot = &e_cache->string_slots[slot_idx]; - E_CacheNode *node = 0; - for(E_CacheNode *n = slot->first; n != 0; n = n->string_next) - { - if(e_key_match(parent_key, n->bundle.parent_key) && str8_match(n->bundle.string, string, 0)) - { - node = n; - break; - } - } - if(node == 0) - { - e_cache->key_id_gen += 1; - E_Key key = {e_cache->key_id_gen}; - U64 key_hash = e_hash_from_string(5381, str8_struct(&key)); - U64 key_slot_idx = key_hash%e_cache->key_slots_count; - E_CacheSlot *key_slot = &e_cache->key_slots[key_slot_idx]; - node = push_array(e_cache->arena, E_CacheNode, 1); - node->key = key; - SLLQueuePush_N(slot->first, slot->last, node, string_next); - SLLQueuePush_N(key_slot->first, key_slot->last, node, key_next); - node->bundle.parent_key = parent_key; - node->bundle.string = push_str8_copy(e_cache->arena, string); - } - return node->key; -} - -internal E_Key -e_key_from_stringf(char *fmt, ...) -{ - Temp scratch = scratch_begin(0, 0); - va_list args; - va_start(args, fmt); - String8 string = push_str8fv(scratch.arena, fmt, args); - E_Key result = e_key_from_string(string); - va_end(args); - scratch_end(scratch); - return result; -} - -//- rjf: base key -> node helper - -internal E_CacheBundle * -e_cache_bundle_from_key(E_Key key) -{ - U64 hash = e_hash_from_string(5381, str8_struct(&key)); - U64 slot_idx = hash%e_cache->key_slots_count; - E_CacheSlot *slot = &e_cache->key_slots[slot_idx]; - E_CacheNode *node = 0; - for(E_CacheNode *n = slot->first; n != 0; n = n->key_next) - { - if(e_key_match(n->key, key)) - { - node = n; - break; - } - } - E_CacheBundle *bundle = &e_cache_bundle_nil; - if(node != 0) - { - bundle = &node->bundle; - } - return bundle; -} - -//- rjf: bundle -> pipeline stage outputs - -internal E_Parse -e_parse_from_bundle(E_CacheBundle *bundle) -{ - if(bundle != &e_cache_bundle_nil && !(bundle->flags & E_CacheBundleFlag_Parse)) - { - bundle->flags |= E_CacheBundleFlag_Parse; - bundle->parse = e_push_parse_from_string(e_cache->arena, bundle->string); - } - E_Parse parse = bundle->parse; - return parse; -} - -internal E_IRTreeAndType -e_irtree_from_bundle(E_CacheBundle *bundle) -{ - if(bundle != &e_cache_bundle_nil && !(bundle->flags & E_CacheBundleFlag_IRTree)) - { - bundle->flags |= E_CacheBundleFlag_IRTree; - E_IRTreeAndType overridden = e_irtree_from_key(bundle->parent_key); - E_IRTreeAndType *prev_overridden = e_ir_state->overridden_irtree; - e_ir_state->overridden_irtree = &overridden; - E_Parse parse = e_parse_from_bundle(bundle); - bundle->irtree = e_push_irtree_and_type_from_expr(e_cache->arena, parse.expr); - e_ir_state->overridden_irtree = prev_overridden; - } - E_IRTreeAndType result = bundle->irtree; - return result; -} - -internal String8 -e_bytecode_from_bundle(E_CacheBundle *bundle) -{ - if(bundle != &e_cache_bundle_nil && !(bundle->flags & E_CacheBundleFlag_Bytecode)) - { - bundle->flags |= E_CacheBundleFlag_Bytecode; - Temp scratch = scratch_begin(0, 0); - E_IRTreeAndType irtree = e_irtree_from_bundle(bundle); - E_OpList oplist = e_oplist_from_irtree(scratch.arena, irtree.root); - bundle->bytecode = e_bytecode_from_oplist(e_cache->arena, &oplist); - scratch_end(scratch); - } - String8 result = bundle->bytecode; - return result; -} - -internal E_Interpretation -e_interpretation_from_bundle(E_CacheBundle *bundle) -{ - if(bundle != &e_cache_bundle_nil && !(bundle->flags & E_CacheBundleFlag_Interpret)) - { - bundle->flags |= E_CacheBundleFlag_Interpret; - String8 bytecode = e_bytecode_from_bundle(bundle); - E_Interpretation interpret = e_interpret(bytecode); - bundle->interpretation = interpret; - } - E_Interpretation interpret = bundle->interpretation; - return interpret; -} - -//- rjf: comprehensive bundle - -internal E_Eval -e_eval_from_bundle(E_CacheBundle *bundle) -{ - E_Eval eval = - { - .expr = e_parse_from_bundle(bundle).expr, - .irtree = e_irtree_from_bundle(bundle), - .bytecode = e_bytecode_from_bundle(bundle), - }; - E_Interpretation interpretation = e_interpretation_from_bundle(bundle); - eval.code = interpretation.code; - eval.value = interpretation.value; - eval.space = interpretation.space; - return eval; -} - -//- rjf: string-based helpers -// TODO(rjf): (replace the old bundle APIs here) - -//////////////////////////////// -//~ rjf: Key Extension Functions - -internal E_Key -e_key_wrap(E_Key key, String8 string) -{ - e_parent_key_push(key); - E_Key result = e_key_from_string(string); - e_parent_key_pop(); - return result; -} - -internal E_Key -e_key_wrapf(E_Key key, char *fmt, ...) -{ - Temp scratch = scratch_begin(0, 0); - va_list args; - va_start(args, fmt); - String8 string = push_str8fv(scratch.arena, fmt, args); - E_Key result = e_key_wrap(key, string); - va_end(args); - scratch_end(scratch); - return result; -} diff --git a/src/eval/eval_cache.h b/src/eval/eval_cache.h deleted file mode 100644 index 8d27b4e4..00000000 --- a/src/eval/eval_cache.h +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright (c) 2024 Epic Games Tools -// Licensed under the MIT license (https://opensource.org/license/mit/) - -#ifndef EVAL_CACHE_H -#define EVAL_CACHE_H - -//////////////////////////////// -//~ rjf: Cache Key Type - -typedef struct E_Key E_Key; -struct E_Key -{ - U64 u64; -}; - -//////////////////////////////// -//~ rjf: Cache Types - -typedef U32 E_CacheBundleFlags; -enum -{ - E_CacheBundleFlag_Parse = (1<<0), - E_CacheBundleFlag_IRTree = (1<<1), - E_CacheBundleFlag_Bytecode = (1<<2), - E_CacheBundleFlag_Interpret = (1<<3), -}; - -typedef struct E_CacheBundle E_CacheBundle; -struct E_CacheBundle -{ - E_CacheBundleFlags flags; - E_Key parent_key; - String8 string; - E_Parse parse; - E_IRTreeAndType irtree; - String8 bytecode; - E_Interpretation interpretation; -}; - -typedef struct E_CacheNode E_CacheNode; -struct E_CacheNode -{ - E_CacheNode *string_next; - E_CacheNode *key_next; - E_Key key; - E_CacheBundle bundle; -}; - -typedef struct E_CacheLookup E_CacheLookup; -struct E_CacheLookup -{ - E_CacheNode *node; - U64 hash; -}; - -typedef struct E_CacheSlot E_CacheSlot; -struct E_CacheSlot -{ - E_CacheNode *first; - E_CacheNode *last; -}; - -typedef struct E_CacheParentNode E_CacheParentNode; -struct E_CacheParentNode -{ - E_CacheParentNode *next; - E_Key key; -}; - -typedef struct E_Cache E_Cache; -struct E_Cache -{ - Arena *arena; - U64 arena_eval_start_pos; - U64 key_id_gen; - U64 key_slots_count; - E_CacheSlot *key_slots; - U64 string_slots_count; - E_CacheSlot *string_slots; - E_CacheParentNode *top_parent_node; - E_CacheParentNode *free_parent_node; -}; - -//////////////////////////////// -//~ rjf: Globals - -thread_static E_Cache *e_cache = 0; -read_only global E_CacheBundle e_cache_bundle_nil = {0, {0}, {0}, {{0}, 0, &e_expr_nil, &e_expr_nil}, {&e_irnode_nil}}; - -//////////////////////////////// -//~ rjf: Basic Key Helpers - -internal B32 e_key_match(E_Key a, E_Key b); - -//////////////////////////////// -//~ rjf: Cache Initialization (Required For All Subsequent APIs) - -internal void e_cache_eval_begin(void); - -//////////////////////////////// -//~ rjf: Cache Accessing Functions -// -// The cache uses a unique keying mechanism to refer to some evaluation at -// many layers of analysis. -// -// key -// ________________________________________________ -// / / | \ -// text -> expression -> ir tree and type -> interpretation result -// -// Each one of these calls refers to one stage in this pipeline. The cache will -// only compute what is needed on-demand. If you ask for the full evaluation, -// which is a bundle of artifacts at all layers of analysis, then all stages -// will be computed. -// -// One wrinkle here is that the IR tree generation stage is implicitly -// parameterized by the "overridden" IR tree - this is to enable "parent -// expressions", e.g. `$.x`, or simply `x` assuming `foo` has such a member, -// in the context of some struct `foo` evaluates to the same thing as `foo.x`. -// So even though the primary API shape is based around singular keys, the -// "parent key stack" also implicitly parameterizes all of these (partly -// because it is not relevant in 99% of cases). - -//- rjf: parent key stack -internal E_Key e_parent_key_push(E_Key key); -internal E_Key e_parent_key_pop(void); - -//- rjf: key construction -internal E_Key e_key_from_string(String8 string); -internal E_Key e_key_from_stringf(char *fmt, ...); - -//- rjf: base key -> bundle helper -internal E_CacheBundle *e_cache_bundle_from_key(E_Key key); - -//- rjf: bundle -> pipeline stage outputs -internal E_Parse e_parse_from_bundle(E_CacheBundle *bundle); -internal E_IRTreeAndType e_irtree_from_bundle(E_CacheBundle *bundle); -internal String8 e_bytecode_from_bundle(E_CacheBundle *bundle); -internal E_Interpretation e_interpretation_from_bundle(E_CacheBundle *bundle); -#define e_parse_from_key(key) e_parse_from_bundle(e_cache_bundle_from_key(key)) -#define e_irtree_from_key(key) e_irtree_from_bundle(e_cache_bundle_from_key(key)) -#define e_bytecode_from_key(key) e_bytecode_from_bundle(e_cache_bundle_from_key(key)) -#define e_interpretation_from_key(key) e_interpretation_from_bundle(e_cache_bundle_from_key(key)) - -//- rjf: comprehensive bundle -internal E_Eval e_eval_from_bundle(E_CacheBundle *bundle); -#define e_eval_from_key(key) e_eval_from_bundle(e_cache_bundle_from_key(key)) - -//- rjf: string-based helpers -// TODO(rjf): (replace the old bundle APIs here) - -//////////////////////////////// -//~ rjf: Key Extension Functions - -internal E_Key e_key_wrap(E_Key key, String8 string); -internal E_Key e_key_wrapf(E_Key key, char *fmt, ...); - -#endif // EVAL_CACHE_H diff --git a/src/eval/eval_core.c b/src/eval/eval_core.c index 78892efa..7e8d5757 100644 --- a/src/eval/eval_core.c +++ b/src/eval/eval_core.c @@ -7,7 +7,7 @@ #include "eval/generated/eval.meta.c" //////////////////////////////// -//~ rjf: Basic Helper Functions +//~ rjf: Basic Helpers #if !defined(XXH_IMPLEMENTATION) # define XXH_IMPLEMENTATION @@ -22,7 +22,72 @@ e_hash_from_string(U64 seed, String8 string) return result; } -//- rjf: type key data structures +//////////////////////////////// +//~ rjf: Expr Kind Enum Functions + +internal RDI_EvalOp +e_opcode_from_expr_kind(E_ExprKind kind) +{ + RDI_EvalOp result = RDI_EvalOp_Stop; + switch(kind) + { + case E_ExprKind_Neg: result = RDI_EvalOp_Neg; break; + case E_ExprKind_LogNot: result = RDI_EvalOp_LogNot; break; + case E_ExprKind_BitNot: result = RDI_EvalOp_BitNot; break; + case E_ExprKind_Mul: result = RDI_EvalOp_Mul; break; + case E_ExprKind_Div: result = RDI_EvalOp_Div; break; + case E_ExprKind_Mod: result = RDI_EvalOp_Mod; break; + case E_ExprKind_Add: result = RDI_EvalOp_Add; break; + case E_ExprKind_Sub: result = RDI_EvalOp_Sub; break; + case E_ExprKind_LShift: result = RDI_EvalOp_LShift; break; + case E_ExprKind_RShift: result = RDI_EvalOp_RShift; break; + case E_ExprKind_Less: result = RDI_EvalOp_Less; break; + case E_ExprKind_LsEq: result = RDI_EvalOp_LsEq; break; + case E_ExprKind_Grtr: result = RDI_EvalOp_Grtr; break; + case E_ExprKind_GrEq: result = RDI_EvalOp_GrEq; break; + case E_ExprKind_EqEq: result = RDI_EvalOp_EqEq; break; + case E_ExprKind_NtEq: result = RDI_EvalOp_NtEq; break; + case E_ExprKind_BitAnd: result = RDI_EvalOp_BitAnd; break; + case E_ExprKind_BitXor: result = RDI_EvalOp_BitXor; break; + case E_ExprKind_BitOr: result = RDI_EvalOp_BitOr; break; + case E_ExprKind_LogAnd: result = RDI_EvalOp_LogAnd; break; + case E_ExprKind_LogOr: result = RDI_EvalOp_LogOr; break; + } + return result; +} + +internal B32 +e_expr_kind_is_comparison(E_ExprKind kind) +{ + B32 result = 0; + switch(kind) + { + default:{}break; + case E_ExprKind_EqEq: + case E_ExprKind_NtEq: + case E_ExprKind_Less: + case E_ExprKind_Grtr: + case E_ExprKind_LsEq: + case E_ExprKind_GrEq: + { + result = 1; + }break; + } + return result; +} + +//////////////////////////////// +//~ rjf: Key Type Functions + +internal B32 +e_key_match(E_Key a, E_Key b) +{ + B32 result = (a.u64 == b.u64); + return result; +} + +//////////////////////////////// +//~ rjf: Type Key Type Functions internal void e_type_key_list_push(Arena *arena, E_TypeKeyList *list, E_TypeKey key) @@ -107,7 +172,7 @@ e_space_make(E_SpaceKind kind) } //////////////////////////////// -//~ rjf: Basic Map Functions +//~ rjf: Map Functions //- rjf: string -> num @@ -277,7 +342,7 @@ e_string2expr_map_dec_poison(E_String2ExprMap *map, String8 string) } internal E_Expr * -e_string2expr_lookup(E_String2ExprMap *map, String8 string) +e_string2expr_map_lookup(E_String2ExprMap *map, String8 string) { E_Expr *expr = &e_expr_nil; if(map->slots_count != 0) @@ -340,6 +405,43 @@ e_string2typekey_map_lookup(E_String2TypeKeyMap *map, String8 string) return key; } +//- rjf: auto hooks + +internal E_AutoHookMap +e_auto_hook_map_make(Arena *arena, U64 slots_count) +{ + E_AutoHookMap map = {0}; + map.slots_count = slots_count; + map.slots = push_array(arena, E_AutoHookSlot, map.slots_count); + return map; +} + +internal void +e_auto_hook_map_insert_new_(Arena *arena, E_AutoHookMap *map, E_AutoHookParams *params) +{ + E_TypeKey type_key = params->type_key; + if(params->type_pattern.size != 0) + { + E_Parse parse = e_push_parse_from_string(arena, params->type_pattern); + type_key = e_type_key_from_expr(parse.expr); + } + E_AutoHookNode *node = push_array(arena, E_AutoHookNode, 1); + node->type_string = str8_skip_chop_whitespace(e_type_string_from_key(arena, type_key)); + U8 pattern_split = '?'; + node->type_pattern_parts = str8_split(arena, params->type_pattern, &pattern_split, 1, StringSplitFlag_KeepEmpties); + node->expr = e_parse_from_string(params->tag_expr_string).expr; + if(!e_type_key_match(e_type_key_zero(), type_key)) + { + U64 hash = e_hash_from_string(5381, node->type_string); + U64 slot_idx = hash%map->slots_count; + SLLQueuePush_N(map->slots[slot_idx].first, map->slots[slot_idx].last, node, hash_next); + } + else + { + SLLQueuePush_N(map->first_pattern, map->last_pattern, node, pattern_order_next); + } +} + //////////////////////////////// //~ rjf: Debug-Info-Driven Map Building Functions @@ -464,13 +566,529 @@ e_push_member_map_from_rdi_voff(Arena *arena, RDI_Parsed *rdi, U64 voff) } //////////////////////////////// -//~ rjf: Base Evaluation Context Selection +//~ rjf: Cache Creation & Selection + +internal E_Cache * +e_cache_alloc(void) +{ + Arena *arena = arena_alloc(); + E_Cache *cache = push_array(arena, E_Cache, 1); + cache->arena = arena; + cache->arena_eval_start_pos = arena_pos(arena); + return cache; +} + +internal void +e_cache_release(E_Cache *cache) +{ + arena_release(cache->arena); +} + +internal void +e_select_cache(E_Cache *cache) +{ + e_cache = cache; +} + +//////////////////////////////// +//~ rjf: Evaluation Phase Markers internal void e_select_base_ctx(E_BaseCtx *ctx) { + //- rjf: select base context if(ctx->modules == 0) { ctx->modules = &e_module_nil; } if(ctx->primary_module == 0) { ctx->primary_module = &e_module_nil; } e_base_ctx = ctx; - e_base_ctx_gen += 1; + + //- rjf: reset the evaluation cache + arena_pop_to(e_cache->arena, e_cache->arena_eval_start_pos); + e_cache->key_id_gen = 0; + e_cache->key_slots_count = 4096; + e_cache->key_slots = push_array(e_cache->arena, E_CacheSlot, e_cache->key_slots_count); + e_cache->string_slots_count = 4096; + e_cache->string_slots = push_array(e_cache->arena, E_CacheSlot, e_cache->string_slots_count); + e_cache->free_parent_node = 0; + e_cache->top_parent_node = 0; + e_cache->cons_id_gen = 0; + e_cache->cons_content_slots_count = 256; + e_cache->cons_key_slots_count = 256; + e_cache->cons_content_slots = push_array(e_cache->arena, E_ConsTypeSlot, e_cache->cons_content_slots_count); + e_cache->cons_key_slots = push_array(e_cache->arena, E_ConsTypeSlot, e_cache->cons_key_slots_count); + e_cache->member_cache_slots_count = 256; + e_cache->member_cache_slots = push_array(e_cache->arena, E_MemberCacheSlot, e_cache->member_cache_slots_count); + e_cache->type_cache_slots_count = 1024; + e_cache->type_cache_slots = push_array(e_cache->arena, E_TypeCacheSlot, e_cache->type_cache_slots_count); + e_cache->file_type_key = e_type_key_cons(.kind = E_TypeKind_Set, + .name = str8_lit("file"), + .irext = E_TYPE_IREXT_FUNCTION_NAME(file), + .access = E_TYPE_ACCESS_FUNCTION_NAME(file), + .expand = + { + .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(file), + .range= E_TYPE_EXPAND_RANGE_FUNCTION_NAME(file), + }); + e_cache->folder_type_key = e_type_key_cons(.kind = E_TypeKind_Set, + .name = str8_lit("folder"), + .expand = + { + .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(folder), + .range = E_TYPE_EXPAND_RANGE_FUNCTION_NAME(folder), + .id_from_num = E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(folder), + .num_from_id = E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_NAME(folder), + }); + e_cache->thread_ip_procedure = rdi_procedure_from_voff(e_base_ctx->primary_module->rdi, e_base_ctx->thread_ip_voff); + e_cache->used_expr_map = push_array(e_cache->arena, E_UsedExprMap, 1); + e_cache->used_expr_map->slots_count = 64; + e_cache->used_expr_map->slots = push_array(e_cache->arena, E_UsedExprSlot, e_cache->used_expr_map->slots_count); + e_cache->type_auto_hook_cache_map = push_array(e_cache->arena, E_TypeAutoHookCacheMap, 1); + e_cache->type_auto_hook_cache_map->slots_count = 256; + e_cache->type_auto_hook_cache_map->slots = push_array(e_cache->arena, E_TypeAutoHookCacheSlot, e_cache->type_auto_hook_cache_map->slots_count); + e_cache->string_id_gen = 0; + e_cache->string_id_map = push_array(e_cache->arena, E_StringIDMap, 1); + e_cache->string_id_map->id_slots_count = 1024; + e_cache->string_id_map->id_slots = push_array(e_cache->arena, E_StringIDSlot, e_cache->string_id_map->id_slots_count); + e_cache->string_id_map->hash_slots_count = 1024; + e_cache->string_id_map->hash_slots = push_array(e_cache->arena, E_StringIDSlot, e_cache->string_id_map->hash_slots_count); +} + +internal void +e_select_ir_ctx(E_IRCtx *ctx) +{ + if(ctx->regs_map == 0) { ctx->regs_map = &e_string2num_map_nil; } + if(ctx->reg_alias_map == 0) { ctx->reg_alias_map = &e_string2num_map_nil; } + if(ctx->locals_map == 0) { ctx->locals_map = &e_string2num_map_nil; } + if(ctx->member_map == 0) { ctx->member_map = &e_string2num_map_nil; } + if(ctx->macro_map == 0) { ctx->macro_map = push_array(e_cache->arena, E_String2ExprMap, 1); ctx->macro_map[0] = e_string2expr_map_make(e_cache->arena, 512); } + e_ir_ctx = ctx; +} + +//////////////////////////////// +//~ rjf: Cache Accessing Functions + +//- rjf: parent key stack + +internal E_Key +e_parent_key_push(E_Key key) +{ + E_Key top = {0}; + if(e_cache->top_parent_node != 0) + { + top = e_cache->top_parent_node->key; + } + E_CacheParentNode *n = e_cache->free_parent_node; + if(n != 0) + { + SLLStackPop(e_cache->free_parent_node); + } + else + { + n = push_array(e_cache->arena, E_CacheParentNode, 1); + } + SLLStackPush(e_cache->top_parent_node, n); + n->key = key; + return top; +} + +internal E_Key +e_parent_key_pop(void) +{ + E_CacheParentNode *n = e_cache->top_parent_node; + SLLStackPop(e_cache->top_parent_node); + SLLStackPush(e_cache->free_parent_node, n); + E_Key popped = n->key; + return popped; +} + +//- rjf: key construction + +internal E_Key +e_key_from_string(String8 string) +{ + E_Key parent_key = {0}; + if(e_cache->top_parent_node) + { + parent_key = e_cache->top_parent_node->key; + } + U64 hash = e_hash_from_string(parent_key.u64, string); + U64 slot_idx = hash%e_cache->string_slots_count; + E_CacheSlot *slot = &e_cache->string_slots[slot_idx]; + E_CacheNode *node = 0; + for(E_CacheNode *n = slot->first; n != 0; n = n->string_next) + { + if(e_key_match(parent_key, n->bundle.parent_key) && str8_match(n->bundle.string, string, 0)) + { + node = n; + break; + } + } + if(node == 0) + { + e_cache->key_id_gen += 1; + E_Key key = {e_cache->key_id_gen}; + U64 key_hash = e_hash_from_string(5381, str8_struct(&key)); + U64 key_slot_idx = key_hash%e_cache->key_slots_count; + E_CacheSlot *key_slot = &e_cache->key_slots[key_slot_idx]; + node = push_array(e_cache->arena, E_CacheNode, 1); + SLLQueuePush_N(slot->first, slot->last, node, string_next); + SLLQueuePush_N(key_slot->first, key_slot->last, node, key_next); + node->bundle.key = key; + node->bundle.parent_key = parent_key; + node->bundle.string = push_str8_copy(e_cache->arena, string); + } + return node->bundle.key; +} + +internal E_Key +e_key_from_stringf(char *fmt, ...) +{ + Temp scratch = scratch_begin(0, 0); + va_list args; + va_start(args, fmt); + String8 string = push_str8fv(scratch.arena, fmt, args); + E_Key result = e_key_from_string(string); + va_end(args); + scratch_end(scratch); + return result; +} + +internal E_Key +e_key_from_expr(E_Expr *expr) +{ + Temp scratch = scratch_begin(0, 0); + String8 string = e_string_from_expr(scratch.arena, expr, str8_zero()); + E_Key key = e_key_from_string(string); + scratch_end(scratch); + return key; +} + +//- rjf: base key -> node helper + +internal E_CacheBundle * +e_cache_bundle_from_key(E_Key key) +{ + U64 hash = e_hash_from_string(5381, str8_struct(&key)); + U64 slot_idx = hash%e_cache->key_slots_count; + E_CacheSlot *slot = &e_cache->key_slots[slot_idx]; + E_CacheNode *node = 0; + for(E_CacheNode *n = slot->first; n != 0; n = n->key_next) + { + if(e_key_match(n->bundle.key, key)) + { + node = n; + break; + } + } + E_CacheBundle *bundle = &e_cache_bundle_nil; + if(node != 0) + { + bundle = &node->bundle; + } + return bundle; +} + +//- rjf: bundle -> pipeline stage outputs + +internal E_Parse +e_parse_from_bundle(E_CacheBundle *bundle) +{ + if(bundle != &e_cache_bundle_nil && !(bundle->flags & E_CacheBundleFlag_Parse)) + { + bundle->flags |= E_CacheBundleFlag_Parse; + bundle->parse = e_push_parse_from_string(e_cache->arena, bundle->string); + } + E_Parse parse = bundle->parse; + return parse; +} + +internal E_IRTreeAndType +e_irtree_from_bundle(E_CacheBundle *bundle) +{ + if(bundle != &e_cache_bundle_nil && !(bundle->flags & E_CacheBundleFlag_IRTree)) + { + bundle->flags |= E_CacheBundleFlag_IRTree; + E_IRTreeAndType overridden = e_irtree_from_key(bundle->parent_key); + E_Parse parse = e_parse_from_bundle(bundle); + bundle->irtree = e_push_irtree_and_type_from_expr(e_cache->arena, &overridden, 0, 0, parse.expr); + } + E_IRTreeAndType result = bundle->irtree; + return result; +} + +internal String8 +e_bytecode_from_bundle(E_CacheBundle *bundle) +{ + if(bundle != &e_cache_bundle_nil && !(bundle->flags & E_CacheBundleFlag_Bytecode)) + { + bundle->flags |= E_CacheBundleFlag_Bytecode; + Temp scratch = scratch_begin(0, 0); + E_IRTreeAndType irtree = e_irtree_from_bundle(bundle); + E_OpList oplist = e_oplist_from_irtree(scratch.arena, irtree.root); + bundle->bytecode = e_bytecode_from_oplist(e_cache->arena, &oplist); + scratch_end(scratch); + } + String8 result = bundle->bytecode; + return result; +} + +internal E_Interpretation +e_interpretation_from_bundle(E_CacheBundle *bundle) +{ + if(bundle != &e_cache_bundle_nil && !(bundle->flags & E_CacheBundleFlag_Interpret)) + { + bundle->flags |= E_CacheBundleFlag_Interpret; + String8 bytecode = e_bytecode_from_bundle(bundle); + E_Interpretation interpret = e_interpret(bytecode); + bundle->interpretation = interpret; + } + E_Interpretation interpret = bundle->interpretation; + return interpret; +} + +//- rjf: comprehensive bundle + +internal E_Eval +e_eval_from_bundle(E_CacheBundle *bundle) +{ + E_Eval eval = + { + .key = bundle->key, + .expr = e_parse_from_bundle(bundle).expr, + .irtree = e_irtree_from_bundle(bundle), + .bytecode = e_bytecode_from_bundle(bundle), + }; + E_Interpretation interpretation = e_interpretation_from_bundle(bundle); + eval.code = interpretation.code; + eval.value = interpretation.value; + eval.space = interpretation.space; + return eval; +} + +internal E_Eval +e_value_eval_from_eval(E_Eval eval) +{ + ProfBeginFunction(); + if(eval.irtree.mode == E_Mode_Offset) + { + E_TypeKey type_key = e_type_key_unwrap(eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative); + E_TypeKind type_kind = e_type_kind_from_key(type_key); + if(type_kind == E_TypeKind_Array) + { + eval.irtree.mode = E_Mode_Value; + } + else + { + U64 type_byte_size = e_type_byte_size_from_key(type_key); + Rng1U64 value_vaddr_range = r1u64(eval.value.u64, eval.value.u64 + type_byte_size); + MemoryZeroStruct(&eval.value); + if(!e_type_key_match(type_key, e_type_key_zero()) && + type_byte_size <= sizeof(E_Value) && + e_space_read(eval.space, &eval.value, value_vaddr_range)) + { + eval.irtree.mode = E_Mode_Value; + + // rjf: mask&shift, for bitfields + if(type_kind == E_TypeKind_Bitfield && type_byte_size <= sizeof(U64)) + { + Temp scratch = scratch_begin(0, 0); + E_Type *type = e_type_from_key__cached(type_key); + U64 valid_bits_mask = 0; + for(U64 idx = 0; idx < type->count; idx += 1) + { + valid_bits_mask |= (1ull<> type->off; + eval.value.u64 = eval.value.u64 & valid_bits_mask; + eval.irtree.type_key = type->direct_type_key; + scratch_end(scratch); + } + + // rjf: manually sign-extend + switch(type_kind) + { + default: break; + case E_TypeKind_Char8: + case E_TypeKind_S8: {eval.value.s64 = (S64)*((S8 *)&eval.value.u64);}break; + case E_TypeKind_Char16: + case E_TypeKind_S16: {eval.value.s64 = (S64)*((S16 *)&eval.value.u64);}break; + case E_TypeKind_Char32: + case E_TypeKind_S32: {eval.value.s64 = (S64)*((S32 *)&eval.value.u64);}break; + } + } + } + } + ProfEnd(); + return eval; +} + +//- rjf: string-based helpers +// TODO(rjf): (replace the old bundle APIs here) + +//- rjf: type key -> auto hooks + +internal E_ExprList +e_auto_hook_exprs_from_type_key(Arena *arena, E_TypeKey type_key) +{ + ProfBeginFunction(); + E_ExprList exprs = {0}; + if(e_ir_ctx != 0) + { + Temp scratch = scratch_begin(&arena, 1); + E_AutoHookMap *map = e_ir_ctx->auto_hook_map; + String8 type_string = str8_skip_chop_whitespace(e_type_string_from_key(scratch.arena, type_key)); + + //- rjf: gather exact-type-key-matches from the map + if(map != 0 && map->slots_count != 0) + { + U64 hash = e_hash_from_string(5381, type_string); + U64 slot_idx = hash%map->slots_count; + for(E_AutoHookNode *n = map->slots[slot_idx].first; n != 0; n = n->hash_next) + { + if(str8_match(n->type_string, type_string, 0)) + { + e_expr_list_push(arena, &exprs, n->expr); + } + } + } + + //- rjf: gather fuzzy matches from all patterns in the map + if(map != 0 && map->first_pattern != 0) + { + for(E_AutoHookNode *auto_hook_node = map->first_pattern; + auto_hook_node != 0; + auto_hook_node = auto_hook_node->pattern_order_next) + { + B32 fits_this_type_string = 1; + U64 scan_pos = 0; + for(String8Node *n = auto_hook_node->type_pattern_parts.first; n != 0; n = n->next) + { + if(n->string.size == 0) + { + continue; + } + U64 pattern_part_pos = str8_find_needle(type_string, scan_pos, n->string, 0); + if(pattern_part_pos >= type_string.size) + { + fits_this_type_string = 0; + break; + } + scan_pos = pattern_part_pos + n->string.size; + } + if(fits_this_type_string) + { + e_expr_list_push(arena, &exprs, auto_hook_node->expr); + } + } + } + + scratch_end(scratch); + } + ProfEnd(); + return exprs; +} + +internal E_ExprList +e_auto_hook_exprs_from_type_key__cached(E_TypeKey type_key) +{ + E_ExprList exprs = {0}; + { + U64 hash = e_hash_from_string(5381, str8_struct(&type_key)); + U64 slot_idx = hash%e_cache->type_auto_hook_cache_map->slots_count; + E_TypeAutoHookCacheNode *node = 0; + for(E_TypeAutoHookCacheNode *n = e_cache->type_auto_hook_cache_map->slots[slot_idx].first; + n != 0; + n = n->next) + { + if(e_type_key_match(n->key, type_key)) + { + node = n; + } + } + if(node == 0) + { + node = push_array(e_cache->arena, E_TypeAutoHookCacheNode, 1); + SLLQueuePush(e_cache->type_auto_hook_cache_map->slots[slot_idx].first, e_cache->type_auto_hook_cache_map->slots[slot_idx].last, node); + node->key = type_key; + node->exprs = e_auto_hook_exprs_from_type_key(e_cache->arena, type_key); + } + exprs = node->exprs; + } + return exprs; +} + +//- rjf: string IDs + +internal U64 +e_id_from_string(String8 string) +{ + U64 hash = e_hash_from_string(5381, string); + U64 hash_slot_idx = hash%e_cache->string_id_map->hash_slots_count; + E_StringIDNode *node = 0; + for(E_StringIDNode *n = e_cache->string_id_map->hash_slots[hash_slot_idx].first; n != 0; n = n->hash_next) + { + if(str8_match(n->string, string, 0)) + { + node = n; + break; + } + } + if(node == 0) + { + e_cache->string_id_gen += 1; + U64 id = e_cache->string_id_gen; + U64 id_slot_idx = id%e_cache->string_id_map->id_slots_count; + node = push_array(e_cache->arena, E_StringIDNode, 1); + SLLQueuePush_N(e_cache->string_id_map->hash_slots[hash_slot_idx].first, e_cache->string_id_map->hash_slots[hash_slot_idx].last, node, hash_next); + SLLQueuePush_N(e_cache->string_id_map->id_slots[id_slot_idx].first, e_cache->string_id_map->hash_slots[id_slot_idx].last, node, id_next); + node->id = id; + node->string = push_str8_copy(e_cache->arena, string); + } + U64 result = node->id; + return result; +} + +internal String8 +e_string_from_id(U64 id) +{ + U64 id_slot_idx = id%e_cache->string_id_map->id_slots_count; + E_StringIDNode *node = 0; + for(E_StringIDNode *n = e_cache->string_id_map->id_slots[id_slot_idx].first; n != 0; n = n->id_next) + { + if(n->id == id) + { + node = n; + break; + } + } + String8 result = {0}; + if(node != 0) + { + result = node->string; + } + return result; +} + +//////////////////////////////// +//~ rjf: Key Extension Functions + +internal E_Key +e_key_wrap(E_Key key, String8 string) +{ + e_parent_key_push(key); + E_Key result = e_key_from_string(string); + e_parent_key_pop(); + return result; +} + +internal E_Key +e_key_wrapf(E_Key key, char *fmt, ...) +{ + Temp scratch = scratch_begin(0, 0); + va_list args; + va_start(args, fmt); + String8 string = push_str8fv(scratch.arena, fmt, args); + E_Key result = e_key_wrap(key, string); + va_end(args); + scratch_end(scratch); + return result; } diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index c6a8c504..3893e0ec 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -4,6 +4,15 @@ #ifndef EVAL_CORE_H #define EVAL_CORE_H +//////////////////////////////// +//~ rjf: Evaluation Key Type + +typedef struct E_Key E_Key; +struct E_Key +{ + U64 u64; +}; + //////////////////////////////// //~ rjf: Messages @@ -309,6 +318,7 @@ struct E_IRTreeAndType typedef struct E_Eval E_Eval; struct E_Eval { + E_Key key; E_Expr *expr; E_IRTreeAndType irtree; String8 bytecode; @@ -417,7 +427,7 @@ struct E_TypeExpandInfo #define E_TYPE_IREXT_FUNCTION_DEF(name) internal E_TYPE_IREXT_FUNCTION_SIG(E_TYPE_IREXT_FUNCTION_NAME(name)) typedef E_TYPE_IREXT_FUNCTION_SIG(E_TypeIRExtFunctionType); -#define E_TYPE_ACCESS_FUNCTION_SIG(name) E_IRTreeAndType name(Arena *arena, E_Expr *expr, E_IRTreeAndType *lhs_irtree) +#define E_TYPE_ACCESS_FUNCTION_SIG(name) E_IRTreeAndType name(Arena *arena, E_IRTreeAndType *overridden, E_Expr *expr, E_IRTreeAndType *lhs_irtree) #define E_TYPE_ACCESS_FUNCTION_NAME(name) e_type_access__##name #define E_TYPE_ACCESS_FUNCTION_DEF(name) internal E_TYPE_ACCESS_FUNCTION_SIG(E_TYPE_ACCESS_FUNCTION_NAME(name)) typedef E_TYPE_ACCESS_FUNCTION_SIG(E_TypeAccessFunctionType); @@ -473,6 +483,44 @@ struct E_Type E_TypeExpandRule expand; }; +//////////////////////////////// +//~ rjf: Constructed Type Types + +typedef struct E_ConsTypeParams E_ConsTypeParams; +struct E_ConsTypeParams +{ + Arch arch; + E_TypeKind kind; + E_TypeFlags flags; + String8 name; + E_TypeKey direct_key; + U64 count; + U64 depth; + E_Member *members; + E_EnumVal *enum_vals; + E_Expr **args; + E_TypeIRExtFunctionType *irext; + E_TypeAccessFunctionType *access; + E_TypeExpandRule expand; +}; + +typedef struct E_ConsTypeNode E_ConsTypeNode; +struct E_ConsTypeNode +{ + E_ConsTypeNode *key_next; + E_ConsTypeNode *content_next; + E_TypeKey key; + E_ConsTypeParams params; + U64 byte_size; +}; + +typedef struct E_ConsTypeSlot E_ConsTypeSlot; +struct E_ConsTypeSlot +{ + E_ConsTypeNode *first; + E_ConsTypeNode *last; +}; + //////////////////////////////// //~ rjf: Modules @@ -614,6 +662,8 @@ struct E_AutoHookParams typedef B32 E_SpaceRWFunction(void *user_data, E_Space space, void *out, Rng1U64 offset_range); +//- rjf: base context + typedef struct E_BaseCtx E_BaseCtx; struct E_BaseCtx { @@ -635,6 +685,300 @@ struct E_BaseCtx E_SpaceRWFunction *space_write; }; +//- rjf: ir generation context + +typedef struct E_IRCtx E_IRCtx; +struct E_IRCtx +{ + E_String2NumMap *regs_map; + E_String2NumMap *reg_alias_map; + E_String2NumMap *locals_map; // (within `primary_module`) + E_String2NumMap *member_map; // (within `primary_module`) + E_String2ExprMap *macro_map; + E_AutoHookMap *auto_hook_map; +}; + +//////////////////////////////// +//~ rjf: Parse Results + +typedef struct E_Parse E_Parse; +struct E_Parse +{ + E_TokenArray tokens; + E_Token *last_token; + E_Expr *expr; + E_Expr *last_expr; + E_MsgList msgs; +}; + +//////////////////////////////// +//~ rjf: Bytecode Interpretation Types + +typedef struct E_Interpretation E_Interpretation; +struct E_Interpretation +{ + E_Value value; + E_Space space; + E_InterpretationCode code; +}; + +//////////////////////////////// +//~ rjf: Core Evaluation Cache Types + +//- rjf: unpacked type cache + +typedef struct E_TypeCacheNode E_TypeCacheNode; +struct E_TypeCacheNode +{ + E_TypeCacheNode *next; + E_TypeKey key; + E_Type *type; +}; + +typedef struct E_TypeCacheSlot E_TypeCacheSlot; +struct E_TypeCacheSlot +{ + E_TypeCacheNode *first; + E_TypeCacheNode *last; +}; + +//- rjf: member lookup cache types + +typedef struct E_MemberHashNode E_MemberHashNode; +struct E_MemberHashNode +{ + E_MemberHashNode *next; + U64 member_idx; +}; + +typedef struct E_MemberHashSlot E_MemberHashSlot; +struct E_MemberHashSlot +{ + E_MemberHashNode *first; + E_MemberHashNode *last; +}; + +typedef struct E_MemberFilterNode E_MemberFilterNode; +struct E_MemberFilterNode +{ + E_MemberFilterNode *next; + String8 filter; + E_MemberArray members_filtered; +}; + +typedef struct E_MemberFilterSlot E_MemberFilterSlot; +struct E_MemberFilterSlot +{ + E_MemberFilterNode *first; + E_MemberFilterNode *last; +}; + +typedef struct E_MemberCacheNode E_MemberCacheNode; +struct E_MemberCacheNode +{ + E_MemberCacheNode *next; + E_TypeKey key; + E_MemberArray members; + U64 member_hash_slots_count; + E_MemberHashSlot *member_hash_slots; + U64 member_filter_slots_count; + E_MemberFilterSlot *member_filter_slots; +}; + +typedef struct E_MemberCacheSlot E_MemberCacheSlot; +struct E_MemberCacheSlot +{ + E_MemberCacheNode *first; + E_MemberCacheNode *last; +}; + +//- rjf: used expression map + +typedef struct E_UsedExprNode E_UsedExprNode; +struct E_UsedExprNode +{ + E_UsedExprNode *next; + E_UsedExprNode *prev; + E_Expr *expr; +}; + +typedef struct E_UsedExprSlot E_UsedExprSlot; +struct E_UsedExprSlot +{ + E_UsedExprNode *first; + E_UsedExprNode *last; +}; + +typedef struct E_UsedExprMap E_UsedExprMap; +struct E_UsedExprMap +{ + U64 slots_count; + E_UsedExprSlot *slots; +}; + +//- rjf: type key -> auto hook expression list cache + +typedef struct E_TypeAutoHookCacheNode E_TypeAutoHookCacheNode; +struct E_TypeAutoHookCacheNode +{ + E_TypeAutoHookCacheNode *next; + E_TypeKey key; + E_ExprList exprs; +}; + +typedef struct E_TypeAutoHookCacheSlot E_TypeAutoHookCacheSlot; +struct E_TypeAutoHookCacheSlot +{ + E_TypeAutoHookCacheNode *first; + E_TypeAutoHookCacheNode *last; +}; + +typedef struct E_TypeAutoHookCacheMap E_TypeAutoHookCacheMap; +struct E_TypeAutoHookCacheMap +{ + U64 slots_count; + E_TypeAutoHookCacheSlot *slots; +}; + +//- rjf: string ID cache + +typedef struct E_StringIDNode E_StringIDNode; +struct E_StringIDNode +{ + E_StringIDNode *hash_next; + E_StringIDNode *id_next; + U64 id; + String8 string; +}; + +typedef struct E_StringIDSlot E_StringIDSlot; +struct E_StringIDSlot +{ + E_StringIDNode *first; + E_StringIDNode *last; +}; + +typedef struct E_StringIDMap E_StringIDMap; +struct E_StringIDMap +{ + U64 id_slots_count; + E_StringIDSlot *id_slots; + U64 hash_slots_count; + E_StringIDSlot *hash_slots; +}; + +//- rjf: cache evaluation bundles + +typedef U32 E_CacheBundleFlags; +enum +{ + E_CacheBundleFlag_Parse = (1<<0), + E_CacheBundleFlag_IRTree = (1<<1), + E_CacheBundleFlag_Bytecode = (1<<2), + E_CacheBundleFlag_Interpret = (1<<3), +}; + +typedef struct E_CacheBundle E_CacheBundle; +struct E_CacheBundle +{ + E_CacheBundleFlags flags; + E_Key key; + E_Key parent_key; + String8 string; + E_Parse parse; + E_IRTreeAndType irtree; + String8 bytecode; + E_Interpretation interpretation; +}; + +typedef struct E_CacheNode E_CacheNode; +struct E_CacheNode +{ + E_CacheNode *string_next; + E_CacheNode *key_next; + E_CacheBundle bundle; +}; + +typedef struct E_CacheLookup E_CacheLookup; +struct E_CacheLookup +{ + E_CacheNode *node; + U64 hash; +}; + +typedef struct E_CacheSlot E_CacheSlot; +struct E_CacheSlot +{ + E_CacheNode *first; + E_CacheNode *last; +}; + +//- rjf: parent stack + +typedef struct E_CacheParentNode E_CacheParentNode; +struct E_CacheParentNode +{ + E_CacheParentNode *next; + E_Key key; +}; + +//- rjf: main cache state type + +typedef struct E_Cache E_Cache; +struct E_Cache +{ + //- rjf: root arena + Arena *arena; + U64 arena_eval_start_pos; + + //- rjf: key ID generation counter + U64 key_id_gen; + + //- rjf: key -> bundle, string -> bundle tables + U64 key_slots_count; + E_CacheSlot *key_slots; + U64 string_slots_count; + E_CacheSlot *string_slots; + + //- rjf: parent stack + E_CacheParentNode *top_parent_node; + E_CacheParentNode *free_parent_node; + + //- rjf: unpacked context + RDI_Procedure *thread_ip_procedure; + + //- rjf: [types] JIT-constructed types tables + U64 cons_id_gen; + U64 cons_content_slots_count; + U64 cons_key_slots_count; + E_ConsTypeSlot *cons_content_slots; + E_ConsTypeSlot *cons_key_slots; + + //- rjf: [types] build-in constructed type keys + E_TypeKey file_type_key; + E_TypeKey folder_type_key; + + //- rjf: [types] member cache table + U64 member_cache_slots_count; + E_MemberCacheSlot *member_cache_slots; + + //- rjf: [types] unpacked type cache + U64 type_cache_slots_count; + E_TypeCacheSlot *type_cache_slots; + + //- rjf: [ir] ir gen options + B32 disallow_autohooks; + B32 disallow_chained_fastpaths; + + //- rjf: [ir] ir caches + E_UsedExprMap *used_expr_map; + E_TypeAutoHookCacheMap *type_auto_hook_cache_map; + + //- rjf: [ir] string ID cache + U64 string_id_gen; + E_StringIDMap *string_id_map; +}; + //////////////////////////////// //~ rjf: Generated Code @@ -647,18 +991,33 @@ read_only global E_String2NumMap e_string2num_map_nil = {0}; read_only global E_String2ExprMap e_string2expr_map_nil = {0}; read_only global E_Expr e_expr_nil = {&e_expr_nil, &e_expr_nil, &e_expr_nil, &e_expr_nil, &e_expr_nil}; read_only global E_IRNode e_irnode_nil = {&e_irnode_nil, &e_irnode_nil, &e_irnode_nil}; -read_only global E_Eval e_eval_nil = {&e_expr_nil, {&e_irnode_nil}}; +read_only global E_Eval e_eval_nil = {{0}, &e_expr_nil, {&e_irnode_nil}}; read_only global E_Module e_module_nil = {&rdi_parsed_nil}; +read_only global E_CacheBundle e_cache_bundle_nil = {0, {0}, {0}, {0}, {{0}, 0, &e_expr_nil, &e_expr_nil}, {&e_irnode_nil}}; thread_static E_BaseCtx *e_base_ctx = 0; -thread_static U64 e_base_ctx_gen = 0; +thread_static E_IRCtx *e_ir_ctx = 0; +thread_static E_Cache *e_cache = 0; //////////////////////////////// -//~ rjf: Basic Helper Functions +//~ rjf: Basic Helpers internal U64 e_hash_from_string(U64 seed, String8 string); #define e_value_u64(v) (E_Value){.u64 = (v)} -//- rjf: type key data structures +//////////////////////////////// +//~ rjf: Expr Kind Enum Functions + +internal RDI_EvalOp e_opcode_from_expr_kind(E_ExprKind kind); +internal B32 e_expr_kind_is_comparison(E_ExprKind kind); + +//////////////////////////////// +//~ rjf: Key Type Functions + +internal B32 e_key_match(E_Key a, E_Key b); + +//////////////////////////////// +//~ rjf: Type Key Type Functions + internal void e_type_key_list_push(Arena *arena, E_TypeKeyList *list, E_TypeKey key); internal void e_type_key_list_push_front(Arena *arena, E_TypeKeyList *list, E_TypeKey key); internal E_TypeKeyList e_type_key_list_copy(Arena *arena, E_TypeKeyList *src); @@ -676,7 +1035,7 @@ internal void e_msg_list_concat_in_place(E_MsgList *dst, E_MsgList *to_push); internal E_Space e_space_make(E_SpaceKind kind); //////////////////////////////// -//~ rjf: Basic Map Functions +//~ rjf: Map Functions //- rjf: string -> num internal E_String2NumMap e_string2num_map_make(Arena *arena, U64 slot_count); @@ -691,13 +1050,18 @@ internal E_String2ExprMap 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); internal void e_string2expr_map_inc_poison(E_String2ExprMap *map, String8 string); internal void e_string2expr_map_dec_poison(E_String2ExprMap *map, String8 string); -internal E_Expr *e_string2expr_lookup(E_String2ExprMap *map, String8 string); +internal E_Expr *e_string2expr_map_lookup(E_String2ExprMap *map, String8 string); //- rjf: string -> type-key internal E_String2TypeKeyMap e_string2typekey_map_make(Arena *arena, U64 slots_count); internal void e_string2typekey_map_insert(Arena *arena, E_String2TypeKeyMap *map, String8 string, E_TypeKey key); internal E_TypeKey e_string2typekey_map_lookup(E_String2TypeKeyMap *map, String8 string); +//- rjf: auto hooks +internal E_AutoHookMap e_auto_hook_map_make(Arena *arena, U64 slots_count); +internal void e_auto_hook_map_insert_new_(Arena *arena, E_AutoHookMap *map, E_AutoHookParams *params); +#define e_auto_hook_map_insert_new(arena, map, ...) e_auto_hook_map_insert_new_((arena), (map), &(E_AutoHookParams){.type_key = zero_struct, __VA_ARGS__}) + //////////////////////////////// //~ rjf: Debug-Info-Driven Map Building Functions @@ -705,8 +1069,102 @@ internal E_String2NumMap *e_push_locals_map_from_rdi_voff(Arena *arena, RDI_Pars internal E_String2NumMap *e_push_member_map_from_rdi_voff(Arena *arena, RDI_Parsed *rdi, U64 voff); //////////////////////////////// -//~ rjf: Base Evaluation Context Selection +//~ rjf: Cache Creation & Selection + +internal E_Cache *e_cache_alloc(void); +internal void e_cache_release(E_Cache *cache); +internal void e_select_cache(E_Cache *cache); + +//////////////////////////////// +//~ rjf: Evaluation Phase Markers internal void e_select_base_ctx(E_BaseCtx *ctx); +internal void e_select_ir_ctx(E_IRCtx *ctx); + +//////////////////////////////// +//~ rjf: Base Cache Accessing Functions +// +// The cache uses a unique keying mechanism to refer to some evaluation at +// many layers of analysis. +// +// key +// ________________________________________________ +// / / | \ +// text -> expression -> ir tree and type -> interpretation result +// +// Each one of these calls refers to one stage in this pipeline. The cache will +// only compute what is needed on-demand. If you ask for the full evaluation, +// which is a bundle of artifacts at all layers of analysis, then all stages +// will be computed. +// +// One wrinkle here is that the IR tree generation stage is implicitly +// parameterized by the "overridden" IR tree - this is to enable "parent +// expressions", e.g. `$.x`, or simply `x` assuming `foo` has such a member, +// in the context of some struct `foo` evaluates to the same thing as `foo.x`. +// So even though the primary API shape is based around singular keys, the +// "parent key stack" also implicitly parameterizes all of these (partly +// because it is not relevant in 99% of cases). + +//- rjf: parent key stack +internal E_Key e_parent_key_push(E_Key key); +internal E_Key e_parent_key_pop(void); +#define E_ParentKey(key) DeferLoop(e_parent_key_push(key), e_parent_key_pop()) + +//- rjf: key construction +internal E_Key e_key_from_string(String8 string); +internal E_Key e_key_from_stringf(char *fmt, ...); +internal E_Key e_key_from_expr(E_Expr *expr); + +//- rjf: base key -> bundle helper +internal E_CacheBundle *e_cache_bundle_from_key(E_Key key); + +//- rjf: bundle -> pipeline stage outputs +internal E_Parse e_parse_from_bundle(E_CacheBundle *bundle); +internal E_IRTreeAndType e_irtree_from_bundle(E_CacheBundle *bundle); +internal String8 e_bytecode_from_bundle(E_CacheBundle *bundle); +internal E_Interpretation e_interpretation_from_bundle(E_CacheBundle *bundle); +#define e_parse_from_key(key) e_parse_from_bundle(e_cache_bundle_from_key(key)) +#define e_irtree_from_key(key) e_irtree_from_bundle(e_cache_bundle_from_key(key)) +#define e_bytecode_from_key(key) e_bytecode_from_bundle(e_cache_bundle_from_key(key)) +#define e_interpretation_from_key(key) e_interpretation_from_bundle(e_cache_bundle_from_key(key)) + +//- rjf: comprehensive bundle +internal E_Eval e_eval_from_bundle(E_CacheBundle *bundle); +internal E_Eval e_value_eval_from_eval(E_Eval eval); +#define e_eval_from_key(key) e_eval_from_bundle(e_cache_bundle_from_key(key)) +#define e_value_from_key(key) (e_value_eval_from_eval(e_eval_from_key(key)).value) + +//- rjf: string-based helpers +#define e_parse_from_string(string) e_parse_from_bundle(e_cache_bundle_from_key(e_key_from_string(string))) +#define e_irtree_from_string(string) e_irtree_from_bundle(e_cache_bundle_from_key(e_key_from_string(string))) +#define e_bytecode_from_string(string) e_bytecode_from_bundle(e_cache_bundle_from_key(e_key_from_string(string))) +#define e_interpretation_from_string(string) e_interpretation_from_bundle(e_cache_bundle_from_key(e_key_from_string(string))) +#define e_eval_from_string(string) e_eval_from_key(e_key_from_string(string)) +#define e_eval_from_stringf(...) e_eval_from_key(e_key_from_stringf(__VA_ARGS__)) +#define e_value_from_string(string) e_value_eval_from_eval(e_eval_from_string(string)).value +#define e_value_from_stringf(...) e_value_eval_from_eval(e_eval_from_stringf(__VA_ARGS__)).value +// TODO(rjf): (replace the old bundle APIs here) + +//- rjf: expr-based helpers +#define e_eval_from_expr(expr) e_eval_from_key(e_key_from_expr(expr)) +#define e_value_from_expr(expr) e_value_eval_from_eval(e_eval_from_expr(expr)).value + +//- rjf: type key -> auto hooks +internal E_ExprList e_auto_hook_exprs_from_type_key(Arena *arena, E_TypeKey type_key); +internal E_ExprList e_auto_hook_exprs_from_type_key__cached(E_TypeKey type_key); + +//- rjf: string IDs +internal U64 e_id_from_string(String8 string); +internal String8 e_string_from_id(U64 id); + +//////////////////////////////// +//~ rjf: Key Extension Functions + +internal E_Key e_key_wrap(E_Key key, String8 string); +internal E_Key e_key_wrapf(E_Key key, char *fmt, ...); + +//- rjf: eval-based helpers +#define e_eval_wrap(eval, string) e_eval_from_key(e_key_wrap((eval).key, (string))) +#define e_eval_wrapf(eval, ...) e_eval_from_key(e_key_wrapf((eval).key, __VA_ARGS__)) #endif // EVAL_CORE_H diff --git a/src/eval/eval_inc.c b/src/eval/eval_inc.c index 2a74cc6b..c4d2222c 100644 --- a/src/eval/eval_inc.c +++ b/src/eval/eval_inc.c @@ -7,4 +7,3 @@ #include "eval/eval_ir.c" #include "eval/eval_interpret.c" #include "eval/eval_bundles.c" -#include "eval/eval_cache.c" diff --git a/src/eval/eval_inc.h b/src/eval/eval_inc.h index 882fff88..2c46335b 100644 --- a/src/eval/eval_inc.h +++ b/src/eval/eval_inc.h @@ -10,6 +10,5 @@ #include "eval/eval_ir.h" #include "eval/eval_interpret.h" #include "eval/eval_bundles.h" -#include "eval/eval_cache.h" #endif // EVAL_INC_H diff --git a/src/eval/eval_interpret.h b/src/eval/eval_interpret.h index 0c900a5a..0b4f37af 100644 --- a/src/eval/eval_interpret.h +++ b/src/eval/eval_interpret.h @@ -4,17 +4,6 @@ #ifndef EVAL_INTERPRET_H #define EVAL_INTERPRET_H -//////////////////////////////// -//~ rjf: Bytecode Interpretation Types - -typedef struct E_Interpretation E_Interpretation; -struct E_Interpretation -{ - E_Value value; - E_Space space; - E_InterpretationCode code; -}; - //////////////////////////////// //~ rjf: Interpretation Context diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index e355f78c..ce077dc8 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -1,289 +1,6 @@ // Copyright (c) 2024 Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) -//////////////////////////////// -//~ rjf: Expr Kind Enum Functions - -internal RDI_EvalOp -e_opcode_from_expr_kind(E_ExprKind kind) -{ - RDI_EvalOp result = RDI_EvalOp_Stop; - switch(kind) - { - case E_ExprKind_Neg: result = RDI_EvalOp_Neg; break; - case E_ExprKind_LogNot: result = RDI_EvalOp_LogNot; break; - case E_ExprKind_BitNot: result = RDI_EvalOp_BitNot; break; - case E_ExprKind_Mul: result = RDI_EvalOp_Mul; break; - case E_ExprKind_Div: result = RDI_EvalOp_Div; break; - case E_ExprKind_Mod: result = RDI_EvalOp_Mod; break; - case E_ExprKind_Add: result = RDI_EvalOp_Add; break; - case E_ExprKind_Sub: result = RDI_EvalOp_Sub; break; - case E_ExprKind_LShift: result = RDI_EvalOp_LShift; break; - case E_ExprKind_RShift: result = RDI_EvalOp_RShift; break; - case E_ExprKind_Less: result = RDI_EvalOp_Less; break; - case E_ExprKind_LsEq: result = RDI_EvalOp_LsEq; break; - case E_ExprKind_Grtr: result = RDI_EvalOp_Grtr; break; - case E_ExprKind_GrEq: result = RDI_EvalOp_GrEq; break; - case E_ExprKind_EqEq: result = RDI_EvalOp_EqEq; break; - case E_ExprKind_NtEq: result = RDI_EvalOp_NtEq; break; - case E_ExprKind_BitAnd: result = RDI_EvalOp_BitAnd; break; - case E_ExprKind_BitXor: result = RDI_EvalOp_BitXor; break; - case E_ExprKind_BitOr: result = RDI_EvalOp_BitOr; break; - case E_ExprKind_LogAnd: result = RDI_EvalOp_LogAnd; break; - case E_ExprKind_LogOr: result = RDI_EvalOp_LogOr; break; - } - return result; -} - -internal B32 -e_expr_kind_is_comparison(E_ExprKind kind) -{ - B32 result = 0; - switch(kind) - { - default:{}break; - case E_ExprKind_EqEq: - case E_ExprKind_NtEq: - case E_ExprKind_Less: - case E_ExprKind_Grtr: - case E_ExprKind_LsEq: - case E_ExprKind_GrEq: - { - result = 1; - }break; - } - return result; -} - -//////////////////////////////// -//~ rjf: Context Selection Functions (Selection Required For All Subsequent APIs) - -internal void -e_select_ir_ctx(E_IRCtx *ctx) -{ - if(e_ir_state == 0) - { - Arena *arena = arena_alloc(); - e_ir_state = push_array(arena, E_IRState, 1); - e_ir_state->arena = arena; - e_ir_state->arena_eval_start_pos = arena_pos(arena); - } - arena_pop_to(e_ir_state->arena, e_ir_state->arena_eval_start_pos); - if(ctx->regs_map == 0) { ctx->regs_map = &e_string2num_map_nil; } - if(ctx->reg_alias_map == 0) { ctx->reg_alias_map = &e_string2num_map_nil; } - if(ctx->locals_map == 0) { ctx->locals_map = &e_string2num_map_nil; } - if(ctx->member_map == 0) { ctx->member_map = &e_string2num_map_nil; } - if(ctx->macro_map == 0) { ctx->macro_map = push_array(e_ir_state->arena, E_String2ExprMap, 1); ctx->macro_map[0] = e_string2expr_map_make(e_ir_state->arena, 512); } - e_ir_state->ctx = ctx; - e_ir_state->thread_ip_procedure = rdi_procedure_from_voff(e_base_ctx->primary_module->rdi, e_base_ctx->thread_ip_voff); - e_ir_state->used_expr_map = push_array(e_ir_state->arena, E_UsedExprMap, 1); - e_ir_state->used_expr_map->slots_count = 64; - e_ir_state->used_expr_map->slots = push_array(e_ir_state->arena, E_UsedExprSlot, e_ir_state->used_expr_map->slots_count); - e_ir_state->type_auto_hook_cache_map = push_array(e_ir_state->arena, E_TypeAutoHookCacheMap, 1); - e_ir_state->type_auto_hook_cache_map->slots_count = 256; - e_ir_state->type_auto_hook_cache_map->slots = push_array(e_ir_state->arena, E_TypeAutoHookCacheSlot, e_ir_state->type_auto_hook_cache_map->slots_count); - e_ir_state->string_id_gen = 0; - e_ir_state->string_id_map = push_array(e_ir_state->arena, E_StringIDMap, 1); - e_ir_state->string_id_map->id_slots_count = 1024; - e_ir_state->string_id_map->id_slots = push_array(e_ir_state->arena, E_StringIDSlot, e_ir_state->string_id_map->id_slots_count); - e_ir_state->string_id_map->hash_slots_count = 1024; - e_ir_state->string_id_map->hash_slots = push_array(e_ir_state->arena, E_StringIDSlot, e_ir_state->string_id_map->hash_slots_count); - e_ir_state->ir_cache_slots_count = 4096; - e_ir_state->ir_cache_slots = push_array(e_ir_state->arena, E_IRCacheSlot, e_ir_state->ir_cache_slots_count); - String8 builtin_view_rule_names[] = - { - str8_lit_comp("bswap"), - }; - for EachElement(idx, builtin_view_rule_names) - { - E_Expr *expr = e_push_expr(e_ir_state->arena, E_ExprKind_LeafOffset, 0); - expr->type_key = e_type_key_cons(.kind = E_TypeKind_LensSpec, .name = builtin_view_rule_names[idx]); - e_string2expr_map_insert(e_ir_state->arena, ctx->macro_map, builtin_view_rule_names[idx], expr); - } -} - -//////////////////////////////// -//~ rjf: Auto Hooks - -internal E_AutoHookMap -e_auto_hook_map_make(Arena *arena, U64 slots_count) -{ - E_AutoHookMap map = {0}; - map.slots_count = slots_count; - map.slots = push_array(arena, E_AutoHookSlot, map.slots_count); - return map; -} - -internal void -e_auto_hook_map_insert_new_(Arena *arena, E_AutoHookMap *map, E_AutoHookParams *params) -{ - E_TypeKey type_key = params->type_key; - if(params->type_pattern.size != 0) - { - E_Parse parse = e_parse_from_string(params->type_pattern); - type_key = e_type_key_from_expr(parse.expr); - } - E_AutoHookNode *node = push_array(arena, E_AutoHookNode, 1); - node->type_string = str8_skip_chop_whitespace(e_type_string_from_key(arena, type_key)); - U8 pattern_split = '?'; - node->type_pattern_parts = str8_split(arena, params->type_pattern, &pattern_split, 1, StringSplitFlag_KeepEmpties); - node->expr = e_parse_from_string(params->tag_expr_string).expr; - if(!e_type_key_match(e_type_key_zero(), type_key)) - { - U64 hash = e_hash_from_string(5381, node->type_string); - U64 slot_idx = hash%map->slots_count; - SLLQueuePush_N(map->slots[slot_idx].first, map->slots[slot_idx].last, node, hash_next); - } - else - { - SLLQueuePush_N(map->first_pattern, map->last_pattern, node, pattern_order_next); - } -} - -internal E_ExprList -e_auto_hook_exprs_from_type_key(Arena *arena, E_TypeKey type_key) -{ - ProfBeginFunction(); - E_ExprList exprs = {0}; - if(e_ir_state != 0 && e_ir_state->ctx != 0) - { - Temp scratch = scratch_begin(&arena, 1); - E_AutoHookMap *map = e_ir_state->ctx->auto_hook_map; - String8 type_string = str8_skip_chop_whitespace(e_type_string_from_key(scratch.arena, type_key)); - - //- rjf: gather exact-type-key-matches from the map - if(map != 0 && map->slots_count != 0) - { - U64 hash = e_hash_from_string(5381, type_string); - U64 slot_idx = hash%map->slots_count; - for(E_AutoHookNode *n = map->slots[slot_idx].first; n != 0; n = n->hash_next) - { - if(str8_match(n->type_string, type_string, 0)) - { - e_expr_list_push(arena, &exprs, n->expr); - } - } - } - - //- rjf: gather fuzzy matches from all patterns in the map - if(map != 0 && map->first_pattern != 0) - { - for(E_AutoHookNode *auto_hook_node = map->first_pattern; - auto_hook_node != 0; - auto_hook_node = auto_hook_node->pattern_order_next) - { - B32 fits_this_type_string = 1; - U64 scan_pos = 0; - for(String8Node *n = auto_hook_node->type_pattern_parts.first; n != 0; n = n->next) - { - if(n->string.size == 0) - { - continue; - } - U64 pattern_part_pos = str8_find_needle(type_string, scan_pos, n->string, 0); - if(pattern_part_pos >= type_string.size) - { - fits_this_type_string = 0; - break; - } - scan_pos = pattern_part_pos + n->string.size; - } - if(fits_this_type_string) - { - e_expr_list_push(arena, &exprs, auto_hook_node->expr); - } - } - } - - scratch_end(scratch); - } - ProfEnd(); - return exprs; -} - -internal E_ExprList -e_auto_hook_exprs_from_type_key__cached(E_TypeKey type_key) -{ - E_ExprList exprs = {0}; - if(e_ir_state != 0 && e_ir_state->ctx != 0 && e_ir_state->type_auto_hook_cache_map != 0 && e_ir_state->type_auto_hook_cache_map->slots_count != 0) - { - U64 hash = e_hash_from_string(5381, str8_struct(&type_key)); - U64 slot_idx = hash%e_ir_state->type_auto_hook_cache_map->slots_count; - E_TypeAutoHookCacheNode *node = 0; - for(E_TypeAutoHookCacheNode *n = e_ir_state->type_auto_hook_cache_map->slots[slot_idx].first; - n != 0; - n = n->next) - { - if(e_type_key_match(n->key, type_key)) - { - node = n; - } - } - if(node == 0) - { - node = push_array(e_ir_state->arena, E_TypeAutoHookCacheNode, 1); - SLLQueuePush(e_ir_state->type_auto_hook_cache_map->slots[slot_idx].first, e_ir_state->type_auto_hook_cache_map->slots[slot_idx].last, node); - node->key = type_key; - node->exprs = e_auto_hook_exprs_from_type_key(e_type_state->arena, type_key); - } - exprs = node->exprs; - } - return exprs; -} - -//////////////////////////////// -//~ rjf: Evaluated String IDs - -internal U64 -e_id_from_string(String8 string) -{ - U64 hash = e_hash_from_string(5381, string); - U64 hash_slot_idx = hash%e_ir_state->string_id_map->hash_slots_count; - E_StringIDNode *node = 0; - for(E_StringIDNode *n = e_ir_state->string_id_map->hash_slots[hash_slot_idx].first; n != 0; n = n->hash_next) - { - if(str8_match(n->string, string, 0)) - { - node = n; - break; - } - } - if(node == 0) - { - e_ir_state->string_id_gen += 1; - U64 id = e_ir_state->string_id_gen; - U64 id_slot_idx = id%e_ir_state->string_id_map->id_slots_count; - node = push_array(e_ir_state->arena, E_StringIDNode, 1); - SLLQueuePush_N(e_ir_state->string_id_map->hash_slots[hash_slot_idx].first, e_ir_state->string_id_map->hash_slots[hash_slot_idx].last, node, hash_next); - SLLQueuePush_N(e_ir_state->string_id_map->id_slots[id_slot_idx].first, e_ir_state->string_id_map->hash_slots[id_slot_idx].last, node, id_next); - node->id = id; - node->string = push_str8_copy(e_ir_state->arena, string); - } - U64 result = node->id; - return result; -} - -internal String8 -e_string_from_id(U64 id) -{ - U64 id_slot_idx = id%e_ir_state->string_id_map->id_slots_count; - E_StringIDNode *node = 0; - for(E_StringIDNode *n = e_ir_state->string_id_map->id_slots[id_slot_idx].first; n != 0; n = n->id_next) - { - if(n->id == id) - { - node = n; - break; - } - } - String8 result = {0}; - if(node != 0) - { - result = node->string; - } - return result; -} - //////////////////////////////// //~ rjf: IR-ization Functions @@ -594,8 +311,8 @@ e_expr_is_poisoned(E_Expr *expr) { B32 tag_is_poisoned = 0; U64 hash = e_hash_from_string(5381, str8_struct(&expr)); - U64 slot_idx = hash%e_ir_state->used_expr_map->slots_count; - for(E_UsedExprNode *n = e_ir_state->used_expr_map->slots[slot_idx].first; n != 0; n = n->next) + U64 slot_idx = hash%e_cache->used_expr_map->slots_count; + for(E_UsedExprNode *n = e_cache->used_expr_map->slots[slot_idx].first; n != 0; n = n->next) { if(n->expr == expr) { @@ -610,22 +327,22 @@ internal void e_expr_poison(E_Expr *expr) { U64 hash = e_hash_from_string(5381, str8_struct(&expr)); - U64 slot_idx = hash%e_ir_state->used_expr_map->slots_count; - E_UsedExprNode *n = push_array(e_ir_state->arena, E_UsedExprNode, 1); + U64 slot_idx = hash%e_cache->used_expr_map->slots_count; + E_UsedExprNode *n = push_array(e_cache->arena, E_UsedExprNode, 1); n->expr = expr; - DLLPushBack(e_ir_state->used_expr_map->slots[slot_idx].first, e_ir_state->used_expr_map->slots[slot_idx].last, n); + DLLPushBack(e_cache->used_expr_map->slots[slot_idx].first, e_cache->used_expr_map->slots[slot_idx].last, n); } internal void e_expr_unpoison(E_Expr *expr) { U64 hash = e_hash_from_string(5381, str8_struct(&expr)); - U64 slot_idx = hash%e_ir_state->used_expr_map->slots_count; - for(E_UsedExprNode *n = e_ir_state->used_expr_map->slots[slot_idx].first; n != 0; n = n->next) + U64 slot_idx = hash%e_cache->used_expr_map->slots_count; + for(E_UsedExprNode *n = e_cache->used_expr_map->slots[slot_idx].first; n != 0; n = n->next) { if(n->expr == expr) { - DLLRemove(e_ir_state->used_expr_map->slots[slot_idx].first, e_ir_state->used_expr_map->slots[slot_idx].last, n); + DLLRemove(e_cache->used_expr_map->slots[slot_idx].first, e_cache->used_expr_map->slots[slot_idx].last, n); break; } } @@ -775,7 +492,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) E_Expr *exprl = expr->first; E_Expr *exprr = exprl->next; E_IRTreeAndType l = *lhs_irtree; - E_IRTreeAndType r = e_push_irtree_and_type_from_expr(arena, exprr); + E_IRTreeAndType r = e_push_irtree_and_type_from_expr(arena, overridden, 0, 0, exprr); E_TypeKey l_restype = e_type_key_unwrap(l.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKey r_restype = e_type_key_unwrap(r.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind l_restype_kind = e_type_kind_from_key(l_restype); @@ -869,7 +586,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(default) //- rjf: top-level irtree/type extraction internal E_IRTreeAndType -e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) +e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32 disallow_autohooks, B32 disallow_chained_fastpaths, E_Expr *root_expr) { ProfBeginFunction(); Temp scratch = scratch_begin(&arena, 1); @@ -886,9 +603,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) E_Expr *expr; E_IRTreeAndType *prev; }; - E_IRTreeAndType *start_prev = e_ir_state->overridden_irtree; - B32 start_disallow_autohooks = e_ir_state->disallow_autohooks; - Task start_task = {0, root_expr, e_ir_state->overridden_irtree}; + Task start_task = {0, root_expr, overridden}; Task *first_task = &start_task; Task *last_task = first_task; for(Task *t = first_task; t != 0; t = t->next) @@ -901,7 +616,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) //- rjf: select the task's previous ir-tree-and-type as the overridden tree if(t->prev != 0) { - e_ir_state->overridden_irtree = t->prev; + overridden = t->prev; } //- rjf: do expr -> irtree generation for this expression @@ -920,7 +635,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { // rjf: unpack left-hand-side E_Expr *lhs = expr->first; - E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, lhs); + E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, lhs); // rjf: try all IR trees in chain for(E_IRTreeAndType *lhs_irtree_try = &lhs_irtree; lhs_irtree_try != 0; lhs_irtree_try = lhs_irtree_try->prev) @@ -961,7 +676,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) } // rjf: call into hook to do access - result = lhs_access(arena, expr, lhs_irtree_try); + result = lhs_access(arena, overridden, expr, lhs_irtree_try); // rjf: end chain if we found a result if(result.root != &e_irnode_nil) @@ -976,7 +691,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr); E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); E_TypeKey r_type_direct = e_type_key_unwrap(r_type, E_TypeUnwrapFlag_All); @@ -1035,7 +750,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr); E_TypeKey r_type = r_tree.type_key; E_TypeKey r_type_unwrapped = e_type_key_unwrap(r_type, E_TypeUnwrapFlag_AllDecorative); E_TypeKind r_type_unwrapped_kind = e_type_kind_from_key(r_type_unwrapped); @@ -1063,11 +778,11 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) // rjf: unpack operands E_Expr *cast_type_expr = expr->first; E_Expr *casted_expr = cast_type_expr->next; - E_IRTreeAndType cast_irtree = e_push_irtree_and_type_from_expr(arena, cast_type_expr); + E_IRTreeAndType cast_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, cast_type_expr); E_TypeKey cast_type = cast_irtree.type_key; E_TypeKind cast_type_kind = e_type_kind_from_key(cast_type); U64 cast_type_byte_size = e_type_byte_size_from_key(cast_type); - E_IRTreeAndType casted_tree = e_push_irtree_and_type_from_expr(arena, casted_expr); + E_IRTreeAndType casted_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, casted_expr); e_msg_list_concat_in_place(&result.msgs, &casted_tree.msgs); E_TypeKey casted_type = e_type_key_unwrap(casted_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind casted_type_kind = e_type_kind_from_key(casted_type); @@ -1122,7 +837,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) E_Expr *r_expr = expr->first; E_TypeKey r_type = zero_struct; E_Space space = r_expr->space; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); r_type = r_tree.type_key; @@ -1150,7 +865,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { // rjf: evaluate operand tree E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); // rjf: fill output @@ -1164,7 +879,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); @@ -1192,14 +907,14 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) //- rjf: unary operations case E_ExprKind_Pos: { - result = e_push_irtree_and_type_from_expr(arena, expr->first); + result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, expr->first); }break; case E_ExprKind_Neg: case E_ExprKind_BitNot: { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr); E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); RDI_EvalTypeGroup r_type_group = e_type_group_from_kind(r_type_kind); @@ -1232,7 +947,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { // rjf: unpack operand E_Expr *r_expr = expr->first; - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, r_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr); E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); E_TypeKind r_type_kind = e_type_kind_from_key(r_type); RDI_EvalTypeGroup r_type_group = e_type_group_from_kind(r_type_kind); @@ -1287,8 +1002,8 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) B32 is_comparison = e_expr_kind_is_comparison(kind); E_Expr *l_expr = expr->first; E_Expr *r_expr = l_expr->next; - E_IRTreeAndType l_tree = e_push_irtree_and_type_from_expr(arena, l_expr); - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, r_expr); + E_IRTreeAndType l_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, l_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr); e_msg_list_concat_in_place(&result.msgs, &l_tree.msgs); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); E_TypeKey l_type = e_type_key_unwrap(l_tree.type_key, E_TypeUnwrapFlag_AllDecorative); @@ -1511,9 +1226,9 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) E_Expr *c_expr = expr->first; E_Expr *l_expr = c_expr->next; E_Expr *r_expr = l_expr->next; - E_IRTreeAndType c_tree = e_push_irtree_and_type_from_expr(arena, c_expr); - E_IRTreeAndType l_tree = e_push_irtree_and_type_from_expr(arena, l_expr); - E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, r_expr); + E_IRTreeAndType c_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, c_expr); + E_IRTreeAndType l_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, l_expr); + E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, r_expr); e_msg_list_concat_in_place(&result.msgs, &c_tree.msgs); e_msg_list_concat_in_place(&result.msgs, &l_tree.msgs); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); @@ -1556,10 +1271,8 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) //- rjf: call case E_ExprKind_Call: { - B32 start_disallow_chained_fastpaths = e_ir_state->disallow_chained_fastpaths; - e_ir_state->disallow_chained_fastpaths = 1; E_Expr *lhs = expr->first; - E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, lhs); + E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, 1, lhs); E_TypeKey lhs_type_key = lhs_irtree.type_key; E_Type *lhs_type = e_type_from_key__cached(lhs_type_key); @@ -1580,17 +1293,17 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { e_expr_push_child(call, e_expr_ref(arena, arg)); } - result = e_push_irtree_and_type_from_expr(arena, call); + result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, call); // rjf: is "raw"? -> try to return overridden tree, otherwise strip all // lens types from result; disallow auto-hooks if(str8_match(callee->string, str8_lit("raw"), 0)) { - e_ir_state->disallow_autohooks = 1; - if(e_ir_state->overridden_irtree != 0) + disallow_autohooks = 1; + if(overridden != 0) { - result = *e_ir_state->overridden_irtree; - for(E_IRTreeAndType *prev = e_ir_state->overridden_irtree->prev; prev != 0; prev = prev->prev) + result = *overridden; + for(E_IRTreeAndType *prev = overridden->prev; prev != 0; prev = prev->prev) { result = *prev; } @@ -1609,7 +1322,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) Temp scratch = scratch_begin(&arena, 1); // rjf: generate result via first argument to lens - result = e_push_irtree_and_type_from_expr(arena, lhs->next); + result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, lhs->next); // rjf: count extra arguments U64 arg_count = 0; @@ -1632,18 +1345,18 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) // lens types from result; disallow auto-hooks if(str8_match(lhs_type->name, str8_lit("raw"), 0)) { - e_ir_state->disallow_autohooks = 1; - if(e_ir_state->overridden_irtree != 0) + disallow_autohooks = 1; + if(overridden != 0) { - result = *e_ir_state->overridden_irtree; - for(E_IRTreeAndType *prev = e_ir_state->overridden_irtree->prev; prev != 0; prev = prev->prev) + result = *overridden; + for(E_IRTreeAndType *prev = overridden->prev; prev != 0; prev = prev->prev) { result = *prev; } } else { - result = e_push_irtree_and_type_from_expr(arena, lhs->next); + result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, lhs->next); result.type_key = e_type_key_unwrap(result.type_key, E_TypeUnwrapFlag_Lenses); } } @@ -1670,8 +1383,6 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { e_msgf(arena, &result.msgs, E_MsgKind_InterpretationError, expr->location, "Calling this type is not supported."); } - - e_ir_state->disallow_chained_fastpaths = start_disallow_chained_fastpaths; }break; //- rjf: leaf bytecode @@ -1751,7 +1462,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { E_Module *module = e_base_ctx->primary_module; RDI_Parsed *rdi = module->rdi; - RDI_Procedure *procedure = e_ir_state->thread_ip_procedure; + RDI_Procedure *procedure = e_cache->thread_ip_procedure; U64 name_size = 0; U8 *name_ptr = rdi_string_from_idx(rdi, procedure->name_string_idx, &name_size); String8 containing_procedure_name = str8(name_ptr, name_size); @@ -1773,21 +1484,21 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) } //- rjf: try to map name as overridden expression signifier ('$') - if(!string_mapped && str8_match(string, str8_lit("$"), 0) && e_ir_state->overridden_irtree != 0) + if(!string_mapped && str8_match(string, str8_lit("$"), 0) && overridden != 0) { - E_OpList oplist = e_oplist_from_irtree(arena, e_ir_state->overridden_irtree->root); + E_OpList oplist = e_oplist_from_irtree(arena, overridden->root); string_mapped = 1; mapped_bytecode = e_bytecode_from_oplist(arena, &oplist); - mapped_bytecode_mode = e_ir_state->overridden_irtree->mode; - mapped_type_key = e_ir_state->overridden_irtree->type_key; - e_ir_state->disallow_autohooks = 1; + mapped_bytecode_mode = overridden->mode; + mapped_type_key = overridden->type_key; + disallow_autohooks = 1; } //- rjf: try to map name as implicit access of overridden expression ('$.member_name', where the $. prefix is omitted) - if(!string_mapped && e_ir_state->overridden_irtree != 0) + if(!string_mapped && overridden != 0) { - E_Expr *access = e_expr_irext_member_access(scratch.arena, &e_expr_nil, e_ir_state->overridden_irtree, string); - E_IRTreeAndType access_irtree = e_push_irtree_and_type_from_expr(scratch.arena, access); + E_Expr *access = e_expr_irext_member_access(scratch.arena, &e_expr_nil, overridden, string); + E_IRTreeAndType access_irtree = e_push_irtree_and_type_from_expr(scratch.arena, overridden, disallow_autohooks, disallow_chained_fastpaths, access); if(access_irtree.root != &e_irnode_nil) { string_mapped = 1; @@ -1806,7 +1517,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) E_Module *module = e_base_ctx->primary_module; U32 module_idx = (U32)(module - e_base_ctx->modules); RDI_Parsed *rdi = module->rdi; - RDI_Procedure *procedure = e_ir_state->thread_ip_procedure; + RDI_Procedure *procedure = e_cache->thread_ip_procedure; RDI_UDT *udt = rdi_container_udt_from_procedure(rdi, procedure); RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, udt->self_type_idx); E_TypeKey container_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), udt->self_type_idx, module_idx); @@ -1824,7 +1535,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) E_Module *module = e_base_ctx->primary_module; U32 module_idx = (U32)(module - e_base_ctx->modules); RDI_Parsed *rdi = module->rdi; - U64 local_num = e_num_from_string(e_ir_state->ctx->locals_map, string__redirected); + U64 local_num = e_num_from_string(e_ir_ctx->locals_map, string__redirected); if(local_num != 0) { RDI_Local *local = rdi_element_from_name_idx(rdi, Locals, local_num-1); @@ -2073,7 +1784,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) //- rjf: try registers if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("reg"), 0))) { - U64 reg_num = e_num_from_string(e_ir_state->ctx->regs_map, string); + U64 reg_num = e_num_from_string(e_ir_ctx->regs_map, string); if(reg_num != 0) { string_mapped = 1; @@ -2090,7 +1801,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) //- rjf: try register aliases if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("reg"), 0))) { - U64 alias_num = e_num_from_string(e_ir_state->ctx->reg_alias_map, string); + U64 alias_num = e_num_from_string(e_ir_ctx->reg_alias_map, string); if(alias_num != 0) { string_mapped = 1; @@ -2149,13 +1860,13 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) //- rjf: generate IR trees for macros if(!generated) { - E_Expr *macro_expr = e_string2expr_lookup(e_ir_state->ctx->macro_map, string); + E_Expr *macro_expr = e_string2expr_map_lookup(e_ir_ctx->macro_map, string); if(macro_expr != &e_expr_nil) { generated = 1; - e_string2expr_map_inc_poison(e_ir_state->ctx->macro_map, string); - result = e_push_irtree_and_type_from_expr(arena, macro_expr); - e_string2expr_map_dec_poison(e_ir_state->ctx->macro_map, string); + e_string2expr_map_inc_poison(e_ir_ctx->macro_map, string); + result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, macro_expr); + e_string2expr_map_dec_poison(e_ir_ctx->macro_map, string); } } @@ -2213,7 +1924,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { E_Space space = e_space_make(E_SpaceKind_FileSystem); result.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, e_id_from_string(file_path))); - result.type_key = e_type_state->file_type_key; + result.type_key = e_cache->file_type_key; result.mode = E_Mode_Value; } else @@ -2224,7 +1935,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { E_Space space = e_space_make(E_SpaceKind_FileSystem); result.root = e_irtree_set_space(arena, space, e_irtree_const_u(arena, e_id_from_string(folder_path))); - result.type_key = e_type_state->folder_type_key; + result.type_key = e_cache->folder_type_key; result.mode = E_Mode_Value; } } @@ -2241,13 +1952,13 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) }break; case E_ExprKind_Ptr: { - E_IRTreeAndType ptee_irtree = e_push_irtree_and_type_from_expr(arena, expr->first); + E_IRTreeAndType ptee_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, expr->first); result = ptee_irtree; result.type_key = e_type_key_cons_ptr(e_base_ctx->primary_module->arch, result.type_key, 1, 0); }break; case E_ExprKind_Array: { - E_IRTreeAndType element_irtree = e_push_irtree_and_type_from_expr(arena, expr->first); + E_IRTreeAndType element_irtree = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, expr->first); result = element_irtree; result.type_key = e_type_key_cons_array(result.type_key, expr->value.u64, 0); }break; @@ -2261,7 +1972,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) { E_Expr *lhs = expr->first; E_Expr *rhs = lhs->next; - result = e_push_irtree_and_type_from_expr(arena, rhs); + result = e_push_irtree_and_type_from_expr(arena, overridden, disallow_autohooks, disallow_chained_fastpaths, rhs); if(lhs->kind != E_ExprKind_LeafIdentifier) { e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->location, "Left side of assignment must be an unused identifier."); @@ -2270,7 +1981,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) } //- rjf: check chained expressions for simple wrappers - if(!e_ir_state->disallow_chained_fastpaths) + if(!disallow_chained_fastpaths) { struct { @@ -2310,7 +2021,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) if(e_type_kind_is_pointer_or_ref(type_kind) || type_kind == E_TypeKind_Array) { - E_Expr *lens_spec_expr = e_string2expr_lookup(e_ir_state->ctx->macro_map, str8_lit("array")); + E_Expr *lens_spec_expr = e_string2expr_map_lookup(e_ir_ctx->macro_map, str8_lit("array")); E_TypeKey lens_spec_type_key = lens_spec_expr->type_key; E_Type *lens_spec_type = e_type_from_key__cached(lens_spec_type_key); result.type_key = e_type_key_cons(.kind = E_TypeKind_Lens, @@ -2360,7 +2071,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) } //- rjf: find any auto hooks according to this generation's type - if(!e_ir_state->disallow_autohooks && result.mode != E_Mode_Null) + if(!disallow_autohooks && result.mode != E_Mode_Null) { E_ExprList exprs = e_auto_hook_exprs_from_type_key__cached(result.type_key); for(E_ExprNode *n = exprs.first; n != 0; n = n->next) @@ -2382,12 +2093,6 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *root_expr) } } - ////////////////////////////// - //- rjf: reset the overridden settings to whatever they were before this task list - // - e_ir_state->overridden_irtree = start_prev; - e_ir_state->disallow_autohooks = start_disallow_autohooks; - ////////////////////////////// //- rjf: unpoison the tags we used // @@ -2688,40 +2393,3 @@ e_expr_irext_cast(Arena *arena, E_Expr *rhs, E_IRTreeAndType *rhs_irtree, E_Type e_expr_push_child(root, rhs_bytecode); return root; } - -//////////////////////////////// -//~ rjf: IR Cache Functions - -internal E_IRTreeAndType -e_irtree_and_type_from_expr(E_Expr *expr) -{ - U64 hash_parts[] = - { - (U64)expr, - (U64)(e_ir_state->overridden_irtree ? e_ir_state->overridden_irtree->root : 0), - }; - U64 hash = e_hash_from_string(5381, str8((U8 *)hash_parts, sizeof(hash_parts))); - U64 slot_idx = hash%e_ir_state->ir_cache_slots_count; - E_IRCacheSlot *slot = &e_ir_state->ir_cache_slots[slot_idx]; - E_IRCacheNode *node = 0; - for(E_IRCacheNode *n = slot->first; n != 0; n = n->next) - { - if(expr == n->expr && - ((e_ir_state->overridden_irtree == 0 && n->overridden_node == 0) || - (e_ir_state->overridden_irtree != 0 && n->overridden_node == e_ir_state->overridden_irtree->root))) - { - node = n; - break; - } - } - if(node == 0) - { - node = push_array(e_ir_state->arena, E_IRCacheNode, 1); - SLLQueuePush(slot->first, slot->last, node); - node->expr = expr; - node->overridden_node = (e_ir_state->overridden_irtree ? e_ir_state->overridden_irtree->root : 0); - node->irtree = e_push_irtree_and_type_from_expr(e_ir_state->arena, expr); - } - E_IRTreeAndType result = node->irtree; - return result; -} diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index d996d710..2bc467dd 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -4,98 +4,6 @@ #ifndef EVAL_IR_H #define EVAL_IR_H -//////////////////////////////// -//~ rjf: Used Tag Map Data Structure - -typedef struct E_UsedExprNode E_UsedExprNode; -struct E_UsedExprNode -{ - E_UsedExprNode *next; - E_UsedExprNode *prev; - E_Expr *expr; -}; - -typedef struct E_UsedExprSlot E_UsedExprSlot; -struct E_UsedExprSlot -{ - E_UsedExprNode *first; - E_UsedExprNode *last; -}; - -typedef struct E_UsedExprMap E_UsedExprMap; -struct E_UsedExprMap -{ - U64 slots_count; - E_UsedExprSlot *slots; -}; - -//////////////////////////////// -//~ rjf: Type Key -> Auto Hook Expr List Cache - -typedef struct E_TypeAutoHookCacheNode E_TypeAutoHookCacheNode; -struct E_TypeAutoHookCacheNode -{ - E_TypeAutoHookCacheNode *next; - E_TypeKey key; - E_ExprList exprs; -}; - -typedef struct E_TypeAutoHookCacheSlot E_TypeAutoHookCacheSlot; -struct E_TypeAutoHookCacheSlot -{ - E_TypeAutoHookCacheNode *first; - E_TypeAutoHookCacheNode *last; -}; - -typedef struct E_TypeAutoHookCacheMap E_TypeAutoHookCacheMap; -struct E_TypeAutoHookCacheMap -{ - U64 slots_count; - E_TypeAutoHookCacheSlot *slots; -}; - -//////////////////////////////// -//~ rjf: Evaluated String ID Map - -typedef struct E_StringIDNode E_StringIDNode; -struct E_StringIDNode -{ - E_StringIDNode *hash_next; - E_StringIDNode *id_next; - U64 id; - String8 string; -}; - -typedef struct E_StringIDSlot E_StringIDSlot; -struct E_StringIDSlot -{ - E_StringIDNode *first; - E_StringIDNode *last; -}; - -typedef struct E_StringIDMap E_StringIDMap; -struct E_StringIDMap -{ - U64 id_slots_count; - E_StringIDSlot *id_slots; - U64 hash_slots_count; - E_StringIDSlot *hash_slots; -}; - -//////////////////////////////// -//~ rjf: IR Context - -typedef struct E_IRCtx E_IRCtx; -struct E_IRCtx -{ - E_String2NumMap *regs_map; - E_String2NumMap *reg_alias_map; - E_String2NumMap *locals_map; // (within `primary_module`) - E_String2NumMap *member_map; // (within `primary_module`) - E_String2ExprMap *macro_map; - E_AutoHookMap *auto_hook_map; -}; - //////////////////////////////// //~ rjf: IR State @@ -141,37 +49,6 @@ struct E_IRState E_IRCacheSlot *ir_cache_slots; }; -//////////////////////////////// -//~ rjf: Globals - -thread_static E_IRState *e_ir_state = 0; - -//////////////////////////////// -//~ rjf: Expr Kind Enum Functions - -internal RDI_EvalOp e_opcode_from_expr_kind(E_ExprKind kind); -internal B32 e_expr_kind_is_comparison(E_ExprKind kind); - -//////////////////////////////// -//~ rjf: Context Selection Functions (Selection Required For All Subsequent APIs) - -internal void e_select_ir_ctx(E_IRCtx *ctx); - -//////////////////////////////// -//~ rjf: Auto Hooks - -internal E_AutoHookMap e_auto_hook_map_make(Arena *arena, U64 slots_count); -internal void e_auto_hook_map_insert_new_(Arena *arena, E_AutoHookMap *map, E_AutoHookParams *params); -#define e_auto_hook_map_insert_new(arena, map, ...) e_auto_hook_map_insert_new_((arena), (map), &(E_AutoHookParams){.type_key = zero_struct, __VA_ARGS__}) -internal E_ExprList e_auto_hook_exprs_from_type_key(Arena *arena, E_TypeKey type_key); -internal E_ExprList e_auto_hook_exprs_from_type_key__cached(E_TypeKey type_key); - -//////////////////////////////// -//~ rjf: Evaluated String IDs - -internal U64 e_id_from_string(String8 string); -internal String8 e_string_from_id(U64 id); - //////////////////////////////// //~ rjf: IR-ization Functions @@ -211,7 +88,7 @@ internal void e_expr_unpoison(E_Expr *expr); //- rjf: top-level irtree/type extraction E_TYPE_ACCESS_FUNCTION_DEF(default); -internal E_IRTreeAndType e_push_irtree_and_type_from_expr(Arena *arena, E_Expr *expr); +internal E_IRTreeAndType e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *overridden, B32 disallow_autohooks, B32 disallow_chained_fastpaths, E_Expr *root_expr); //- rjf: irtree -> linear ops/bytecode internal void e_append_oplist_from_irtree(Arena *arena, E_IRNode *root, E_Space *current_space, E_OpList *out); @@ -224,9 +101,4 @@ internal E_Expr *e_expr_irext_array_index(Arena *arena, E_Expr *lhs, E_IRTreeAnd internal E_Expr *e_expr_irext_deref(Arena *arena, E_Expr *rhs, E_IRTreeAndType *rhs_irtree); internal E_Expr *e_expr_irext_cast(Arena *arena, E_Expr *rhs, E_IRTreeAndType *rhs_irtree, E_TypeKey type_key); -//////////////////////////////// -//~ rjf: IR Cache Functions - -internal E_IRTreeAndType e_irtree_and_type_from_expr(E_Expr *expr); - #endif // EVAL_IR_H diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index abf9e728..116ddda1 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -1454,47 +1454,3 @@ e_push_parse_from_string(Arena *arena, String8 text) scratch_end(scratch); return parse; } - -//////////////////////////////// -//~ rjf: Parse Cache Functions - -internal void -e_parse_eval_begin(void) -{ - if(e_parse_state == 0) - { - Arena *arena = arena_alloc(); - e_parse_state = push_array(arena, E_ParseState, 1); - e_parse_state->arena = arena; - e_parse_state->arena_eval_start_pos = arena_pos(e_parse_state->arena); - } - arena_pop_to(e_parse_state->arena, e_parse_state->arena_eval_start_pos); - e_parse_state->cache_slots_count = 4096; - e_parse_state->cache_slots = push_array(e_parse_state->arena, E_ParseCacheSlot, e_parse_state->cache_slots_count); -} - -internal E_Parse -e_parse_from_string(String8 string) -{ - U64 hash = e_hash_from_string(5381, string); - U64 slot_idx = hash%e_parse_state->cache_slots_count; - E_ParseCacheSlot *slot = &e_parse_state->cache_slots[slot_idx]; - E_ParseCacheNode *node = 0; - for(E_ParseCacheNode *n = slot->first; n != 0; n = n->next) - { - if(str8_match(n->string, string, 0)) - { - node = n; - break; - } - } - if(node == 0) - { - node = push_array(e_parse_state->arena, E_ParseCacheNode, 1); - SLLQueuePush(slot->first, slot->last, node); - node->string = push_str8_copy(e_parse_state->arena, string); - node->parse = e_push_parse_from_string(e_parse_state->arena, node->string); - } - E_Parse result = node->parse; - return result; -} diff --git a/src/eval/eval_parse.h b/src/eval/eval_parse.h index 418451a9..54af1689 100644 --- a/src/eval/eval_parse.h +++ b/src/eval/eval_parse.h @@ -4,51 +4,6 @@ #ifndef EVAL_PARSE_H #define EVAL_PARSE_H -//////////////////////////////// -//~ rjf: Parse Results - -typedef struct E_Parse E_Parse; -struct E_Parse -{ - E_TokenArray tokens; - E_Token *last_token; - E_Expr *expr; - E_Expr *last_expr; - E_MsgList msgs; -}; - -//////////////////////////////// -//~ rjf: Parse Evaluation State - -typedef struct E_ParseCacheNode E_ParseCacheNode; -struct E_ParseCacheNode -{ - E_ParseCacheNode *next; - String8 string; - E_Parse parse; -}; - -typedef struct E_ParseCacheSlot E_ParseCacheSlot; -struct E_ParseCacheSlot -{ - E_ParseCacheNode *first; - E_ParseCacheNode *last; -}; - -typedef struct E_ParseState E_ParseState; -struct E_ParseState -{ - Arena *arena; - U64 arena_eval_start_pos; - U64 cache_slots_count; - E_ParseCacheSlot *cache_slots; -}; - -//////////////////////////////// -//~ rjf: Globals - -thread_static E_ParseState *e_parse_state = 0; - //////////////////////////////// //~ rjf: Tokenization Functions @@ -86,10 +41,4 @@ internal E_Parse e_push_type_parse_from_text_tokens(Arena *arena, String8 text, internal E_Parse e_push_parse_from_string_tokens__prec(Arena *arena, String8 text, E_TokenArray tokens, S64 max_precedence, U64 max_chain_count); internal E_Parse e_push_parse_from_string(Arena *arena, String8 text); -//////////////////////////////// -//~ rjf: Parse Cache Functions - -internal void e_parse_eval_begin(void); -internal E_Parse e_parse_from_string(String8 string); - #endif // EVAL_PARSE_H diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index ff7af653..6b4156b0 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -222,49 +222,6 @@ e_member_array_from_list(Arena *arena, E_MemberList *list) return array; } -//////////////////////////////// -//~ rjf: Type Evaluation Phase Beginning Marker (Required For All Subsequent APIs) - -internal void -e_type_eval_begin(void) -{ - if(e_type_state == 0) - { - Arena *arena = arena_alloc(); - e_type_state = push_array(arena, E_TypeState, 1); - e_type_state->arena = arena; - e_type_state->arena_eval_start_pos = arena_pos(e_type_state->arena); - } - arena_pop_to(e_type_state->arena, e_type_state->arena_eval_start_pos); - e_type_state->cons_id_gen = 0; - e_type_state->cons_content_slots_count = 256; - e_type_state->cons_key_slots_count = 256; - e_type_state->cons_content_slots = push_array(e_type_state->arena, E_ConsTypeSlot, e_type_state->cons_content_slots_count); - e_type_state->cons_key_slots = push_array(e_type_state->arena, E_ConsTypeSlot, e_type_state->cons_key_slots_count); - e_type_state->member_cache_slots_count = 256; - e_type_state->member_cache_slots = push_array(e_type_state->arena, E_MemberCacheSlot, e_type_state->member_cache_slots_count); - e_type_state->type_cache_slots_count = 1024; - e_type_state->type_cache_slots = push_array(e_type_state->arena, E_TypeCacheSlot, e_type_state->type_cache_slots_count); - e_type_state->file_type_key = e_type_key_cons(.kind = E_TypeKind_Set, - .name = str8_lit("file"), - .irext = E_TYPE_IREXT_FUNCTION_NAME(file), - .access = E_TYPE_ACCESS_FUNCTION_NAME(file), - .expand = - { - .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(file), - .range= E_TYPE_EXPAND_RANGE_FUNCTION_NAME(file), - }); - e_type_state->folder_type_key = e_type_key_cons(.kind = E_TypeKind_Set, - .name = str8_lit("folder"), - .expand = - { - .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(folder), - .range = E_TYPE_EXPAND_RANGE_FUNCTION_NAME(folder), - .id_from_num = E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(folder), - .num_from_id = E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_NAME(folder), - }); -} - //////////////////////////////// //~ rjf: Type Operation Functions @@ -385,8 +342,8 @@ 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]; + U64 content_slot_idx = content_hash%e_cache->cons_content_slots_count; + E_ConsTypeSlot *content_slot = &e_cache->cons_content_slots[content_slot_idx]; E_ConsTypeNode *node = 0; for(E_ConsTypeNode *n = content_slot->first; n != 0; n = n->content_next) { @@ -401,17 +358,17 @@ e_type_key_cons_(E_ConsTypeParams *params) { E_TypeKey key = {E_TypeKeyKind_Cons}; key.u32[0] = (U32)params->kind; - key.u32[1] = (U32)e_type_state->cons_id_gen; - e_type_state->cons_id_gen += 1; + key.u32[1] = (U32)e_cache->cons_id_gen; + e_cache->cons_id_gen += 1; 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); + U64 key_slot_idx = key_hash%e_cache->cons_key_slots_count; + E_ConsTypeSlot *key_slot = &e_cache->cons_key_slots[key_slot_idx]; + E_ConsTypeNode *node = push_array(e_cache->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; MemoryCopyStruct(&node->params, params); - node->params.name = push_str8_copy(e_type_state->arena, params->name); + node->params.name = push_str8_copy(e_cache->arena, params->name); if(node->params.expand.info != 0) { if(node->params.expand.range == 0) {node->params.expand.range = E_TYPE_EXPAND_RANGE_FUNCTION_NAME(default);} @@ -420,32 +377,32 @@ e_type_key_cons_(E_ConsTypeParams *params) } if(params->members != 0) { - node->params.members = push_array(e_type_state->arena, E_Member, params->count); + node->params.members = push_array(e_cache->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); + node->params.members[idx].name = push_str8_copy(e_cache->arena, node->params.members[idx].name); + node->params.members[idx].inheritance_key_chain = e_type_key_list_copy(e_cache->arena, &node->params.members[idx].inheritance_key_chain); U64 opl_off = (node->params.members[idx].off + e_type_byte_size_from_key(node->params.members[idx].type_key)); node->byte_size = Max(node->byte_size, opl_off); } } else if(params->enum_vals != 0) { - node->params.enum_vals = push_array(e_type_state->arena, E_EnumVal, params->count); + node->params.enum_vals = push_array(e_cache->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); + node->params.enum_vals[idx].name = push_str8_copy(e_cache->arena, node->params.enum_vals[idx].name); } node->byte_size = e_type_byte_size_from_key(node->params.direct_key); } else if(params->args != 0) { - node->params.args = push_array(e_type_state->arena, E_Expr *, params->count); + node->params.args = push_array(e_cache->arena, E_Expr *, params->count); for EachIndex(idx, params->count) { - node->params.args[idx] = e_expr_copy(e_type_state->arena, params->args[idx]); + node->params.args[idx] = e_expr_copy(e_cache->arena, params->args[idx]); } } else switch(params->kind) @@ -560,14 +517,14 @@ e_type_key_cons_base(Type *type) internal E_TypeKey e_type_key_file(void) { - E_TypeKey key = e_type_state->file_type_key; + E_TypeKey key = e_cache->file_type_key; return key; } internal E_TypeKey e_type_key_folder(void) { - E_TypeKey key = e_type_state->folder_type_key; + E_TypeKey key = e_cache->folder_type_key; return key; } @@ -669,8 +626,8 @@ e_type_byte_size_from_key(E_TypeKey key) case E_TypeKeyKind_Cons: { 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]; + U64 key_slot_idx = key_hash%e_cache->cons_key_slots_count; + E_ConsTypeSlot *key_slot = &e_cache->cons_key_slots[key_slot_idx]; for(E_ConsTypeNode *node = key_slot->first; node != 0; node = node->key_next) @@ -715,8 +672,8 @@ e_type_from_key(Arena *arena, E_TypeKey key) case E_TypeKeyKind_Cons: { 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]; + U64 key_slot_idx = key_hash%e_cache->cons_key_slots_count; + E_ConsTypeSlot *key_slot = &e_cache->cons_key_slots[key_slot_idx]; for(E_ConsTypeNode *node = key_slot->first; node != 0; node = node->key_next) @@ -1996,9 +1953,9 @@ e_type_from_key__cached(E_TypeKey key) E_Type *type = &e_type_nil; { U64 hash = e_hash_from_string(5381, str8_struct(&key)); - U64 slot_idx = hash%e_type_state->type_cache_slots_count; + U64 slot_idx = hash%e_cache->type_cache_slots_count; E_TypeCacheNode *node = 0; - for(E_TypeCacheNode *n = e_type_state->type_cache_slots[slot_idx].first; n != 0; n = n->next) + for(E_TypeCacheNode *n = e_cache->type_cache_slots[slot_idx].first; n != 0; n = n->next) { if(e_type_key_match(key, n->key)) { @@ -2008,10 +1965,10 @@ e_type_from_key__cached(E_TypeKey key) } if(node == 0) { - node = push_array(e_type_state->arena, E_TypeCacheNode, 1); + node = push_array(e_cache->arena, E_TypeCacheNode, 1); node->key = key; - node->type = e_type_from_key(e_type_state->arena, key); - SLLQueuePush(e_type_state->type_cache_slots[slot_idx].first, e_type_state->type_cache_slots[slot_idx].last, node); + node->type = e_type_from_key(e_cache->arena, key); + SLLQueuePush(e_cache->type_cache_slots[slot_idx].first, e_cache->type_cache_slots[slot_idx].last, node); } type = node->type; } @@ -2022,8 +1979,8 @@ internal E_MemberCacheNode * e_member_cache_node_from_type_key(E_TypeKey key) { U64 hash = e_hash_from_string(5381, str8_struct(&key)); - U64 slot_idx = hash%e_type_state->member_cache_slots_count; - E_MemberCacheSlot *slot = &e_type_state->member_cache_slots[slot_idx]; + U64 slot_idx = hash%e_cache->member_cache_slots_count; + E_MemberCacheSlot *slot = &e_cache->member_cache_slots[slot_idx]; E_MemberCacheNode *node = 0; for(E_MemberCacheNode *n = slot->first; n != 0; n = n->next) { @@ -2035,19 +1992,19 @@ e_member_cache_node_from_type_key(E_TypeKey key) } if(node == 0) { - node = push_array(e_type_state->arena, E_MemberCacheNode, 1); + node = push_array(e_cache->arena, E_MemberCacheNode, 1); SLLQueuePush(slot->first, slot->last, node); node->key = key; - node->members = e_type_data_members_from_key(e_type_state->arena, key); + node->members = e_type_data_members_from_key(e_cache->arena, key); node->member_hash_slots_count = node->members.count; - node->member_hash_slots = push_array(e_type_state->arena, E_MemberHashSlot, node->member_hash_slots_count); + node->member_hash_slots = push_array(e_cache->arena, E_MemberHashSlot, node->member_hash_slots_count); node->member_filter_slots_count = 16; - node->member_filter_slots = push_array(e_type_state->arena, E_MemberFilterSlot, node->member_filter_slots_count); + node->member_filter_slots = push_array(e_cache->arena, E_MemberFilterSlot, node->member_filter_slots_count); for EachIndex(idx, node->members.count) { U64 hash = e_hash_from_string(5381, node->members.v[idx].name); U64 slot_idx = hash%node->member_hash_slots_count; - E_MemberHashNode *n = push_array(e_type_state->arena, E_MemberHashNode, 1); + E_MemberHashNode *n = push_array(e_cache->arena, E_MemberHashNode, 1); SLLQueuePush(node->member_hash_slots[slot_idx].first, node->member_hash_slots[slot_idx].last, n); n->member_idx = idx; } @@ -2083,8 +2040,8 @@ e_type_data_members_from_key_filter__cached(E_TypeKey key, String8 filter) if(filter_node == 0) { Temp scratch = scratch_begin(0, 0); - filter_node = push_array(e_type_state->arena, E_MemberFilterNode, 1); - filter_node->filter = push_str8_copy(e_type_state->arena, filter); + filter_node = push_array(e_cache->arena, E_MemberFilterNode, 1); + filter_node->filter = push_str8_copy(e_cache->arena, filter); E_MemberList member_list__filtered = {0}; for EachIndex(idx, node->members.count) { @@ -2095,7 +2052,7 @@ e_type_data_members_from_key_filter__cached(E_TypeKey key, String8 filter) e_member_list_push(scratch.arena, &member_list__filtered, member); } } - filter_node->members_filtered = e_member_array_from_list(e_type_state->arena, &member_list__filtered); + filter_node->members_filtered = e_member_array_from_list(e_cache->arena, &member_list__filtered); scratch_end(scratch); } members = filter_node->members_filtered; @@ -2300,6 +2257,7 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(omit) irtree_stripped.type_key = type->direct_type_key; irtree_stripped.user_data = stripped_type->irext ? stripped_type->irext(scratch.arena, expr, &irtree_stripped).user_data : 0; E_TypeExpandRule *expand_rule = e_expand_rule_from_type_key(irtree_stripped.type_key); + // TODO(rjf): @eval before expanding a type, ALWAYS select the parent key E_TypeExpandInfo expand_info = expand_rule->info(scratch.arena, expr, &irtree_stripped, filter); if(expand_info.expr_count < 4096) { @@ -2395,14 +2353,9 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(array) U64 count = 1; if(type->args != 0 && type->count > 0) { - E_Expr *count_expr = type->args[0]; - E_IRTreeAndType *prev_overridden_irtree = e_ir_state->overridden_irtree; - e_ir_state->overridden_irtree = irtree; - { - E_Value count_value = e_value_from_expr(count_expr); - count = count_value.u64; - } - e_ir_state->overridden_irtree = prev_overridden_irtree; + E_Key count_key = e_key_from_expr(type->args[0]); + E_Value count_value = e_value_from_key(count_key); + count = count_value.u64; } E_TypeExpandInfo info = {0, count}; return info; @@ -2550,7 +2503,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(slice) default: case E_ExprKind_MemberAccess: { - result = E_TYPE_ACCESS_FUNCTION_NAME(default)(arena, expr, lhs_irtree); + result = E_TYPE_ACCESS_FUNCTION_NAME(default)(arena, overridden, expr, lhs_irtree); }break; case E_ExprKind_ArrayIndex: { diff --git a/src/eval/eval_types.h b/src/eval/eval_types.h index fdbcb08b..451dc8b0 100644 --- a/src/eval/eval_types.h +++ b/src/eval/eval_types.h @@ -20,141 +20,6 @@ enum E_TypeUnwrapFlag_AllDecorative = (E_TypeUnwrapFlag_All & ~E_TypeUnwrapFlag_Pointers) }; -//////////////////////////////// -//~ rjf: Type Evaluation State - -//- rjf: constructed type cache types - -typedef struct E_ConsTypeParams E_ConsTypeParams; -struct E_ConsTypeParams -{ - Arch arch; - E_TypeKind kind; - E_TypeFlags flags; - String8 name; - E_TypeKey direct_key; - U64 count; - U64 depth; - E_Member *members; - E_EnumVal *enum_vals; - E_Expr **args; - E_TypeIRExtFunctionType *irext; - E_TypeAccessFunctionType *access; - E_TypeExpandRule expand; -}; - -typedef struct E_ConsTypeNode E_ConsTypeNode; -struct E_ConsTypeNode -{ - E_ConsTypeNode *key_next; - E_ConsTypeNode *content_next; - E_TypeKey key; - E_ConsTypeParams params; - U64 byte_size; -}; - -typedef struct E_ConsTypeSlot E_ConsTypeSlot; -struct E_ConsTypeSlot -{ - E_ConsTypeNode *first; - E_ConsTypeNode *last; -}; - -//- rjf: unpacked type cache - -typedef struct E_TypeCacheNode E_TypeCacheNode; -struct E_TypeCacheNode -{ - E_TypeCacheNode *next; - E_TypeKey key; - E_Type *type; -}; - -typedef struct E_TypeCacheSlot E_TypeCacheSlot; -struct E_TypeCacheSlot -{ - E_TypeCacheNode *first; - E_TypeCacheNode *last; -}; - -//- rjf: member lookup cache types - -typedef struct E_MemberHashNode E_MemberHashNode; -struct E_MemberHashNode -{ - E_MemberHashNode *next; - U64 member_idx; -}; - -typedef struct E_MemberHashSlot E_MemberHashSlot; -struct E_MemberHashSlot -{ - E_MemberHashNode *first; - E_MemberHashNode *last; -}; - -typedef struct E_MemberFilterNode E_MemberFilterNode; -struct E_MemberFilterNode -{ - E_MemberFilterNode *next; - String8 filter; - E_MemberArray members_filtered; -}; - -typedef struct E_MemberFilterSlot E_MemberFilterSlot; -struct E_MemberFilterSlot -{ - E_MemberFilterNode *first; - E_MemberFilterNode *last; -}; - -typedef struct E_MemberCacheNode E_MemberCacheNode; -struct E_MemberCacheNode -{ - E_MemberCacheNode *next; - E_TypeKey key; - E_MemberArray members; - U64 member_hash_slots_count; - E_MemberHashSlot *member_hash_slots; - U64 member_filter_slots_count; - E_MemberFilterSlot *member_filter_slots; -}; - -typedef struct E_MemberCacheSlot E_MemberCacheSlot; -struct E_MemberCacheSlot -{ - E_MemberCacheNode *first; - E_MemberCacheNode *last; -}; - -//- rjf: bundle - -typedef struct E_TypeState E_TypeState; -struct E_TypeState -{ - Arena *arena; - U64 arena_eval_start_pos; - - // rjf: JIT-constructed types tables - U64 cons_id_gen; - U64 cons_content_slots_count; - U64 cons_key_slots_count; - E_ConsTypeSlot *cons_content_slots; - E_ConsTypeSlot *cons_key_slots; - - // rjf: build-in constructed type keys - E_TypeKey file_type_key; - E_TypeKey folder_type_key; - - // rjf: member cache table - U64 member_cache_slots_count; - E_MemberCacheSlot *member_cache_slots; - - // rjf: unpacked type cache - U64 type_cache_slots_count; - E_TypeCacheSlot *type_cache_slots; -}; - //////////////////////////////// //~ rjf: Globals @@ -171,7 +36,6 @@ global read_only E_TypeExpandRule e_type_expand_rule__default = E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(identity), E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_NAME(identity), }; -thread_static E_TypeState *e_type_state = 0; //////////////////////////////// //~ rjf: Type Kind Enum Functions @@ -192,11 +56,6 @@ internal void e_member_list_push(Arena *arena, E_MemberList *list, E_Member *mem #define e_member_list_push_new(arena, list, ...) e_member_list_push((arena), (list), &(E_Member){.kind = E_MemberKind_DataField, __VA_ARGS__}) internal E_MemberArray e_member_array_from_list(Arena *arena, E_MemberList *list); -//////////////////////////////// -//~ rjf: Type Evaluation Phase Beginning Marker (Required For All Subsequent APIs) - -internal void e_type_eval_begin(void); - //////////////////////////////// //~ rjf: Type Operation Functions diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 5fac14f3..77e7a380 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -586,6 +586,7 @@ ev_block_tree_from_eval(Arena *arena, EV_View *view, String8 filter, E_Eval eval } // rjf: get top-level lookup/expansion info + // TODO(rjf): @eval before expanding a type, ALWAYS select the parent key E_TypeExpandInfo type_expand_info = type_expand_rule->info(arena, t->eval.expr, &t->eval.irtree, filter); EV_ExpandInfo viz_expand_info = viz_expand_rule->info(arena, view, filter, t->eval.expr); @@ -705,7 +706,7 @@ ev_block_tree_from_eval(Arena *arena, EV_View *view, String8 filter, E_Eval eval type_expand_rule->range(arena, type_expand_info.user_data, t->eval.expr, &t->eval.irtree, filter, r1u64(split_relative_idx, split_relative_idx+1), &child_expr, &child_string); if(child_expr != &e_expr_nil) { - E_Eval child_eval = e_eval_from_expr(arena, child_expr); + E_Eval child_eval = e_eval_from_expr(child_expr); EV_Key child_key = child_keys[idx]; Task *task = push_array(scratch.arena, Task, 1); SLLQueuePush(first_task, last_task, task); @@ -725,7 +726,7 @@ ev_block_tree_from_eval(Arena *arena, EV_View *view, String8 filter, E_Eval eval task->next = t->next; t->next = task; task->parent_block = t->parent_block; - task->eval = e_eval_from_expr(arena, t->eval.expr->next); + task->eval = e_eval_from_expr(t->eval.expr->next); task->child_id = t->child_id + 1; task->split_relative_idx = 0; task->default_expanded = t->default_expanded; @@ -1046,7 +1047,7 @@ ev_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 U64 child_id = ev_block_id_from_num(n->v.block, child_num); EV_Key row_key = ev_key_make(ev_hash_from_key(n->v.block->key), child_id); E_Expr *row_expr = range_exprs[idx]; - E_Eval row_eval = e_eval_from_expr(arena, row_expr); + E_Eval row_eval = e_eval_from_expr(row_expr); EV_WindowedRowNode *row_node = push_array(arena, EV_WindowedRowNode, 1); SLLQueuePush(rows.first, rows.last, row_node); rows.count += 1; @@ -2055,7 +2056,7 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) if(ptr_data->type->count == 1) { E_Expr *deref_expr = e_expr_irext_deref(arena, eval.expr, &eval.irtree); - E_Eval deref_eval = e_eval_from_expr(arena, deref_expr); + E_Eval deref_eval = e_eval_from_expr(deref_expr); need_new_task = 1; need_pop = 0; new_task.params = *params; @@ -2105,6 +2106,7 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) expand_data = it->top_task->user_data = push_array(arena, EV_ExpandedTypeData, 1); expand_data->type = e_type_from_key__cached(type_key); expand_data->expand_rule = e_expand_rule_from_type_key(type_key); + // TODO(rjf): @eval before expanding a type, ALWAYS select the parent key expand_data->expand_info = expand_data->expand_rule->info(arena, eval.expr, &eval.irtree, params->filter); } switch(task_idx) @@ -2134,7 +2136,7 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) need_new_task = 1; need_pop = 0; new_task.params = *params; - new_task.eval = e_eval_from_expr(arena, next_expr); + new_task.eval = e_eval_from_expr(next_expr); if(task_idx > 1) { *out_string = str8_lit(", "); diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index de41c742..bed73c3f 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -294,7 +294,7 @@ global read_only EV_Block ev_nil_block = {0}, 0, {0}, - {&e_expr_nil, &e_irnode_nil}, + {{0}, &e_expr_nil, &e_irnode_nil}, {0}, &e_type_expand_rule__default, {0}, diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 0a4e3185..d7a435ec 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1245,7 +1245,7 @@ rd_setting_b32_from_name(String8 name) Temp scratch = scratch_begin(0, 0); String8 value = rd_setting_from_name(name); String8 expr = push_str8f(scratch.arena, "(bool)(%S)", value); - E_Eval eval = e_eval_from_string(scratch.arena, expr); + E_Eval eval = e_eval_from_string(expr); B32 result = !!e_value_eval_from_eval(eval).value.u64; scratch_end(scratch); return result; @@ -1257,7 +1257,7 @@ rd_setting_u64_from_name(String8 name) Temp scratch = scratch_begin(0, 0); String8 value = rd_setting_from_name(name); String8 expr = push_str8f(scratch.arena, "(uint64)(%S)", value); - E_Eval eval = e_eval_from_string(scratch.arena, expr); + E_Eval eval = e_eval_from_string(expr); U64 result = e_value_eval_from_eval(eval).value.u64; scratch_end(scratch); return result; @@ -1269,7 +1269,7 @@ rd_setting_f32_from_name(String8 name) Temp scratch = scratch_begin(0, 0); String8 value = rd_setting_from_name(name); String8 expr = push_str8f(scratch.arena, "(float32)(%S)", value); - E_Eval eval = e_eval_from_string(scratch.arena, expr); + E_Eval eval = e_eval_from_string(expr); F32 result = e_value_eval_from_eval(eval).value.f32; scratch_end(scratch); return result; @@ -2029,7 +2029,7 @@ rd_commit_eval_value_string(E_Eval dst_eval, String8 string) got_commit_data = 1; E_Expr *src_expr = e_parse_from_string(string).expr; E_Expr *src_expr__casted = e_expr_ref_cast(scratch.arena, type_key, src_expr); - E_Eval src_eval = e_eval_from_expr(scratch.arena, src_expr__casted); + E_Eval src_eval = e_eval_from_expr(src_expr__casted); commit_data = push_str8_copy(scratch.arena, str8_struct(&src_eval.value)); commit_data.size = Min(commit_data.size, e_type_byte_size_from_key(type_key)); } @@ -2095,7 +2095,7 @@ rd_commit_eval_value_string(E_Eval dst_eval, String8 string) //- rjf: pointer? -> try to treat new value as numeric value if(!got_commit_data && type_kind == E_TypeKind_Ptr) { - E_Eval src_eval = e_eval_from_string(scratch.arena, string); + E_Eval src_eval = e_eval_from_string(string); E_Eval src_eval_value = e_value_eval_from_eval(src_eval); E_TypeKind src_eval_value_type_kind = e_type_kind_from_key(src_eval_value.irtree.type_key); if((e_type_kind_is_pointer_or_ref(src_eval_value_type_kind) || @@ -2156,7 +2156,7 @@ rd_file_path_from_eval_string(Arena *arena, String8 string) String8 result = {0}; { Temp scratch = scratch_begin(&arena, 1); - E_Eval eval = e_eval_from_string(scratch.arena, string); + E_Eval eval = e_eval_from_string(string); result = rd_file_path_from_eval(arena, eval); scratch_end(scratch); } @@ -2617,7 +2617,7 @@ rd_view_ui(Rng2F32 rect) } // rjf: unpack view's target expression & hash - E_Eval eval = e_eval_from_string(scratch.arena, expr_string); + E_Eval eval = e_eval_from_string(expr_string); Rng1U64 range = r1u64(0, 1024); U128 key = rd_key_from_eval_space_range(eval.space, range, 0); U128 hash = hs_hash_from_key(key, 0); @@ -2709,7 +2709,7 @@ rd_view_ui(Rng2F32 rect) Temp scratch = scratch_begin(0, 0); RD_Font(RD_FontSlot_Code) { - E_Eval eval = e_eval_from_string(scratch.arena, expr_string); + E_Eval eval = e_eval_from_string(expr_string); RD_WatchViewState *ewv = rd_view_state(RD_WatchViewState); UI_ScrollPt2 scroll_pos = rd_view_scroll_pos(); F32 entity_hover_t_rate = rd_setting_b32_from_name(str8_lit("hover_animations")) ? (1 - pow_f32(2, (-60.f * rd_state->frame_dt))) : 1.f; @@ -4260,8 +4260,7 @@ rd_view_ui(Rng2F32 rect) { E_Expr *min_expr = cell_type->args[0]; E_Expr *max_expr = cell_type->args[1]; - E_IRTreeAndType *prev_overridden_irtree = e_ir_state->overridden_irtree; - e_ir_state->overridden_irtree = &cell->eval.irtree; + E_ParentKey(cell->eval.key) { E_TypeKey slider_value_type = e_type_key_unwrap(cell_type->direct_type_key, E_TypeUnwrapFlag_AllDecorative); slider_value_type_kind = e_type_kind_from_key(slider_value_type); @@ -4270,7 +4269,6 @@ rd_view_ui(Rng2F32 rect) cell_slider_min = e_value_from_expr(min_casted); cell_slider_max = e_value_from_expr(max_casted); } - e_ir_state->overridden_irtree = prev_overridden_irtree; } switch(slider_value_type_kind) { @@ -4399,10 +4397,10 @@ rd_view_ui(Rng2F32 rect) } // rjf: view ui contents - E_IRTreeAndType *prev_overridden_irtree = e_ir_state->overridden_irtree; - e_ir_state->overridden_irtree = cell->eval.irtree.prev; - cell_info.view_ui_rule->ui(cell->eval, cell_rect); - e_ir_state->overridden_irtree = prev_overridden_irtree; + E_ParentKey(cell->eval.key) + { + cell_info.view_ui_rule->ui(cell->eval, cell_rect); + } // rjf: loading fill UI_Parent(loading_overlay_container) @@ -4850,15 +4848,11 @@ rd_view_ui(Rng2F32 rect) { Temp scratch = scratch_begin(0, 0); RD_ViewUIRule *view_ui_rule = rd_view_ui_rule_from_string(view_name); - E_Eval expr_eval = e_eval_from_string(scratch.arena, expr_string); - E_IRTreeAndType *prev_overridden_irtree = e_ir_state->overridden_irtree; - e_ir_state->overridden_irtree = &expr_eval.irtree; - for(E_IRTreeAndType *prev = expr_eval.irtree.prev; prev != 0; prev = prev->prev) + E_Eval expr_eval = e_eval_from_string(expr_string); + E_ParentKey(expr_eval.key) { - e_ir_state->overridden_irtree = prev; + view_ui_rule->ui(expr_eval, rect); } - view_ui_rule->ui(expr_eval, rect); - e_ir_state->overridden_irtree = prev_overridden_irtree; scratch_end(scratch); } } @@ -4950,48 +4944,34 @@ rd_view_cfg_from_string(String8 string) internal E_Value rd_view_cfg_value_from_string(String8 string) { - Temp scratch = scratch_begin(0, 0); RD_Cfg *root = rd_view_cfg_from_string(string); String8 expr = root->first->string; - E_Eval eval = e_eval_from_string(scratch.arena, expr); + E_Eval eval = e_eval_from_string(expr); E_Value result = e_value_eval_from_eval(eval).value; - scratch_end(scratch); return result; } internal B32 rd_view_cfg_b32_from_string(String8 string) { - Temp scratch = scratch_begin(0, 0); RD_Cfg *root = rd_view_cfg_from_string(string); - String8 expr = push_str8f(scratch.arena, "(bool)(%S)", root->first->string); - E_Eval eval = e_eval_from_string(scratch.arena, expr); - B32 result = !!e_value_eval_from_eval(eval).value.u64; - scratch_end(scratch); + B32 result = !!e_value_from_stringf("(bool)(%S)", root->first->string).u64; return result; } internal U64 rd_view_cfg_u64_from_string(String8 string) { - Temp scratch = scratch_begin(0, 0); RD_Cfg *root = rd_view_cfg_from_string(string); - String8 expr = push_str8f(scratch.arena, "(uint64)(%S)", root->first->string); - E_Eval eval = e_eval_from_string(scratch.arena, expr); - U64 result = e_value_eval_from_eval(eval).value.u64; - scratch_end(scratch); + U64 result = e_value_from_stringf("(uint64)(%S)", root->first->string).u64; return result; } internal F32 rd_view_cfg_f32_from_string(String8 string) { - Temp scratch = scratch_begin(0, 0); RD_Cfg *root = rd_view_cfg_from_string(string); - String8 expr = push_str8f(scratch.arena, "(float32)(%S)", root->first->string); - E_Eval eval = e_eval_from_string(scratch.arena, expr); - F32 result = e_value_eval_from_eval(eval).value.f32; - scratch_end(scratch); + F32 result = e_value_from_stringf("(float32)(%S)", root->first->string).f32; return result; } @@ -5912,7 +5892,7 @@ rd_window_frame(void) { rd_code_label(1.f, 0, ui_color_from_name(str8_lit("text")), rd_state->drag_drop_regs->expr); ui_spacer(ui_em(2.f, 1.f)); - E_Eval eval = e_eval_from_string(scratch.arena, rd_state->drag_drop_regs->expr); + E_Eval eval = e_eval_from_string(rd_state->drag_drop_regs->expr); if(eval.irtree.mode != E_Mode_Null) { EV_StringParams string_params = {.flags = EV_StringFlag_ReadOnlyDisplayRules, .radix = 10}; @@ -6294,7 +6274,7 @@ rd_window_frame(void) // rjf: evaluate hover evaluation expression, & determine if it evaluates // such that we want to build a hover eval. - E_Eval hover_eval = e_eval_from_string(scratch.arena, hover_eval_expr); + E_Eval hover_eval = e_eval_from_string(hover_eval_expr); { if(hover_eval.msgs.max_kind > E_MsgKind_Null) { @@ -6405,7 +6385,7 @@ rd_window_frame(void) if(query_is_open) { String8 expr = ws->query_regs->expr; - E_Eval eval = e_eval_from_string(scratch.arena, expr); + E_Eval eval = e_eval_from_string(expr); if(eval.msgs.max_kind > E_MsgKind_Null) { query_is_open = 0; @@ -6473,7 +6453,7 @@ rd_window_frame(void) } // rjf: evaluate query expression - E_Eval query_eval = e_eval_from_string(scratch.arena, query_expr); + E_Eval query_eval = e_eval_from_string(query_expr); // rjf: determine & store row-height setting if(ws->query_regs->do_big_rows) @@ -10228,7 +10208,7 @@ rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 str // rjf: try to map as local if(!mapped && kind == TXT_TokenKind_Identifier) { - U64 local_num = e_num_from_string(e_ir_state->ctx->locals_map, string); + U64 local_num = e_num_from_string(e_ir_ctx->locals_map, string); if(local_num != 0) { mapped = 1; @@ -10239,7 +10219,7 @@ rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 str // rjf: try to map as member if(!mapped && kind == TXT_TokenKind_Identifier) { - U64 member_num = e_num_from_string(e_ir_state->ctx->member_map, string); + U64 member_num = e_num_from_string(e_ir_ctx->member_map, string); if(member_num != 0) { mapped = 1; @@ -10250,7 +10230,7 @@ rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 str // rjf: try to map as register if(!mapped) { - U64 reg_num = e_num_from_string(e_ir_state->ctx->regs_map, string); + U64 reg_num = e_num_from_string(e_ir_ctx->regs_map, string); if(reg_num != 0) { mapped = 1; @@ -10261,7 +10241,7 @@ rd_theme_color_from_txt_token_kind_lookup_string(TXT_TokenKind kind, String8 str // rjf: try to map as register alias if(!mapped) { - U64 alias_num = e_num_from_string(e_ir_state->ctx->reg_alias_map, string); + U64 alias_num = e_num_from_string(e_ir_ctx->reg_alias_map, string); if(alias_num != 0) { mapped = 1; @@ -10650,8 +10630,7 @@ rd_regs_fill_slot_from_string(RD_RegSlot slot, String8 string) case RD_RegSlot_PID: goto use_numeric_eval; use_numeric_eval: { - Temp scratch = scratch_begin(0, 0); - E_Eval eval = e_eval_from_string(scratch.arena, string); + E_Eval eval = e_eval_from_string(string); if(eval.msgs.max_kind == E_MsgKind_Null) { E_TypeKind eval_type_kind = e_type_kind_from_key(e_type_key_unwrap(eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative)); @@ -10691,7 +10670,6 @@ rd_regs_fill_slot_from_string(RD_RegSlot slot, String8 string) { log_user_errorf("Couldn't evaluate \"%S\" as an address.", string); } - scratch_end(scratch); }break; } } @@ -10816,6 +10794,7 @@ rd_init(CmdLine *cmdln) rd_state->num_frames_requested = 2; rd_state->seconds_until_autosave = 0.5f; rd_state->match_store = di_match_store_alloc(); + rd_state->eval_cache = e_cache_alloc(); for(U64 idx = 0; idx < ArrayCount(rd_state->cmds_arenas); idx += 1) { rd_state->cmds_arenas[idx] = arena_alloc(); @@ -11815,6 +11794,11 @@ rd_frame(void) } ProfEnd(); + //////////////////////////// + //- rjf: begin evaluation + // + e_select_cache(rd_state->eval_cache); + //////////////////////////// //- rjf: build base evaluation context // @@ -11840,12 +11824,6 @@ rd_frame(void) } e_select_base_ctx(eval_base_ctx); - //////////////////////////// - //- rjf: begin type evaluation - // - e_parse_eval_begin(); - e_type_eval_begin(); - //////////////////////////// //- rjf: build extra types & maps // @@ -12460,11 +12438,6 @@ rd_frame(void) } e_select_interpret_ctx(interpret_ctx, eval_modules_primary->rdi, rip_voff); - //////////////////////////// - //- rjf: begin cached evaluations - // - e_cache_eval_begin(); - //////////////////////////// //- rjf: autosave if needed // @@ -15842,19 +15815,16 @@ Z(getting_started) { if(t->expr->kind == E_ExprKind_LeafIdentifier) { - E_Expr *macro_expr = e_string2expr_lookup(e_ir_state->ctx->macro_map, t->expr->string); - if(macro_expr != &e_expr_nil) + E_Expr *macro_expr = e_string2expr_map_lookup(e_ir_ctx->macro_map, t->expr->string); + E_Eval eval = e_eval_from_string(t->expr->string); + switch(eval.space.kind) { - E_Eval eval = e_eval_from_expr(scratch.arena, macro_expr); - switch(eval.space.kind) + default:{is_static_for_ctrl_thread = 0;}break; + case E_SpaceKind_Null: + case RD_EvalSpaceKind_MetaCfg: { - default:{is_static_for_ctrl_thread = 0;}break; - case E_SpaceKind_Null: - case RD_EvalSpaceKind_MetaCfg: - { - is_static_for_ctrl_thread = 1; - }break; - } + is_static_for_ctrl_thread = 1; + }break; } } for(E_Expr *child = t->expr->first; child != &e_expr_nil; child = child->next) @@ -15874,7 +15844,7 @@ Z(getting_started) String8 non_ctrl_thread_static_condition = src_bp_cnd; if(is_static_for_ctrl_thread) { - E_Eval eval = e_eval_from_string(scratch.arena, src_bp_cnd); + E_Eval eval = e_eval_from_string(src_bp_cnd); E_Eval value_eval = e_value_eval_from_eval(eval); if(value_eval.value.u64 == 0) { diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 936afa92..7edf3690 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -635,6 +635,9 @@ struct RD_State // rjf: dbgi match store DI_MatchStore *match_store; + // rjf: evaluation cache + E_Cache *eval_cache; + // rjf: ambiguous path table (constructed from-scratch each frame) U64 ambiguous_path_slots_count; RD_AmbiguousPathNode **ambiguous_path_slots; diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index a3bd9650..4ff074b6 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -75,14 +75,8 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(commands) for(U64 idx = idx_range.min; idx < idx_range.max; idx += 1, out_idx += 1) { String8 cmd_name = accel->v[idx]; - RD_CmdKindInfo *cmd_info = rd_cmd_kind_info_from_string(cmd_name); - E_TypeKey cmd_type = e_type_key_cons(.kind = E_TypeKind_U64, .name = str8_lit("command")); - cmd_type = e_type_key_cons_meta_description(cmd_type, cmd_info->description); - E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafValue, 0); - expr->type_key = cmd_type; - expr->space = e_space_make(RD_EvalSpaceKind_MetaCmd); - expr->value.u64 = e_id_from_string(cmd_name); - exprs_out[out_idx] = expr; + E_Eval cmd_eval = e_eval_from_stringf("query:commands.%S", cmd_name); + exprs_out[out_idx] = cmd_eval.expr; } } @@ -105,7 +99,7 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(watches) B32 passes_filter = 1; if(filter.size != 0) { - E_Eval eval = e_eval_from_string(scratch.arena, expr); + E_Eval eval = e_eval_from_string(expr); E_Type *type = e_type_from_key__cached(eval.irtree.type_key); if(type->kind != E_TypeKind_Set) { @@ -196,7 +190,7 @@ E_TYPE_EXPAND_INFO_FUNCTION_DEF(locals) E_TypeExpandInfo result = {0}; Temp scratch = scratch_begin(&arena, 1); { - E_String2NumMapNodeArray nodes = e_string2num_map_node_array_from_map(scratch.arena, e_ir_state->ctx->locals_map); + E_String2NumMapNodeArray nodes = e_string2num_map_node_array_from_map(scratch.arena, e_ir_ctx->locals_map); e_string2num_map_node_array_sort__in_place(&nodes); String8List exprs_filtered = {0}; for EachIndex(idx, nodes.count) @@ -768,12 +762,12 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(cfgs) { Rng1U64 read_range = intersect_1u64(cmds_idx_range, idx_range); U64 read_count = dim_1u64(read_range); - E_Expr *commands = e_parse_from_string(str8_lit("query:commands")).expr; - E_IRTreeAndType commands_irtree = e_irtree_and_type_from_expr(commands); + E_Eval cmds_eval = e_eval_from_stringf("query:commands"); for(U64 idx = 0; idx < read_count; idx += 1, dst_idx += 1) { String8 cmd_name = accel->cmds.v[idx + read_range.min - cmds_idx_range.min]; - exprs_out[dst_idx] = e_expr_irext_member_access(arena, commands, &commands_irtree, cmd_name); + E_Eval cmd_eval = e_eval_wrapf(cmds_eval, "$.%S", cmd_name); + exprs_out[dst_idx] = cmd_eval.expr; } } diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 72dfa6a5..24238e73 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1108,14 +1108,14 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) RD_Cfg *w_cfg = style->first; F32 next_pct = 0; #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) - E_IRTreeAndType *prev_overridden_irtree = e_ir_state->overridden_irtree; - e_ir_state->overridden_irtree = &row->eval.irtree; - for(U64 idx = 0; idx < maybe_table_type->count; idx += 1) + E_ParentKey(row->eval.key) { - E_Eval cell_eval = e_eval_from_expr(arena, maybe_table_type->args[idx]); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, cell_eval, .default_pct = 1.f/maybe_table_type->count, .pct = take_pct()); + for(U64 idx = 0; idx < maybe_table_type->count; idx += 1) + { + E_Eval cell_eval = e_eval_from_expr(maybe_table_type->args[idx]); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, cell_eval, .default_pct = 1.f/maybe_table_type->count, .pct = take_pct()); + } } - e_ir_state->overridden_irtree = prev_overridden_irtree; info.can_expand = 0; #undef take_pct } @@ -1229,7 +1229,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } if(cmd_kind == RD_CmdKind_EnableCfg || cmd_kind == RD_CmdKind_DisableCfg) { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(arena, row->eval, "enabled"), + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(row->eval, "enabled"), .flags = RD_WatchCellFlag_Background, .px = floor_f32(ui_top_font_size()*5.f)); } @@ -1237,7 +1237,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) { String8 cmd_name = rd_cmd_kind_info_table[cmd_kind].string; rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, - e_eval_from_stringf(arena, "query:commands.%S", cmd_name), + e_eval_from_stringf("query:commands.%S", cmd_name), .flags = RD_WatchCellFlag_ActivateWithSingleClick|RD_WatchCellFlag_Button, .px = floor_f32(ui_top_font_size()*3.f)); } @@ -1259,7 +1259,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) entity->kind == CTRL_EntityKind_Process || entity->kind == CTRL_EntityKind_Thread) { - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(arena, row->eval, "active"), + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(row->eval, "active"), .edit_string = row->edit_string, .px = floor_f32(ui_top_font_size()*5.f)); } @@ -1271,7 +1271,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) cmd_kind = RD_CmdKind_DeselectEntity; } String8 cmd_name = rd_cmd_kind_info_table[cmd_kind].string; - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_from_stringf(arena, "query:commands.%S", cmd_name), + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_from_stringf("query:commands.%S", cmd_name), .edit_string = row->edit_string, .flags = RD_WatchCellFlag_ActivateWithSingleClick|RD_WatchCellFlag_Button, .px = floor_f32(ui_top_font_size()*3.f)); @@ -1383,7 +1383,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_NoEval|RD_WatchCellFlag_Indented, .default_pct = 0.75f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(arena, row->eval, "lens:hex((uint64)$)"), .default_pct = 0.25f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(row->eval, "lens:hex((uint64)$)"), .default_pct = 0.25f, .pct = take_pct()); #undef take_pct } @@ -1395,12 +1395,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) info.cell_style_key = str8_lit("call_stack_frame"); CTRL_Entity *process = ctrl_process_from_entity(info.callstack_thread); CTRL_Entity *module = ctrl_module_from_process_vaddr(process, info.callstack_vaddr); - E_Space space = rd_eval_space_from_ctrl_entity(module, RD_EvalSpaceKind_MetaCtrlEntity); - E_Expr *expr = e_push_expr(arena, E_ExprKind_LeafOffset, 0); - expr->space = space; - expr->mode = E_Mode_Offset; - expr->type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, str8_lit("module")); - E_Eval module_eval = e_eval_from_expr(arena, expr); + E_Eval module_eval = ctrl_eval_from_handle(module->handle); RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); RD_Cfg *style = rd_cfg_child_from_string(view, info.cell_style_key); RD_Cfg *w_cfg = style->first; @@ -1408,7 +1403,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) #define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_CallStackFrame, row->eval, .default_pct = 0.05f, .pct = take_pct()); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .default_pct = 0.55f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(arena, row->eval, "lens:hex((uint64)$)"), .default_pct = 0.20f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(row->eval, "lens:hex((uint64)$)"), .default_pct = 0.20f, .pct = take_pct()); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, (module == &ctrl_entity_nil ? (E_Eval)zero_struct : module_eval), .default_pct = 0.20f, .pct = take_pct()); #undef take_pct @@ -1430,8 +1425,8 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) .flags = RD_WatchCellFlag_Expr|RD_WatchCellFlag_NoEval|RD_WatchCellFlag_Indented, .default_pct = 0.35f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .default_pct = 0.40f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(arena, row->eval, "typeof(raw($))"), .default_pct = 0.25f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .default_pct = 0.40f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(row->eval, "typeof(raw($))"), .default_pct = 0.25f, .pct = take_pct()); #undef take_pct } @@ -2088,13 +2083,13 @@ RD_VIEW_UI_FUNCTION_DEF(disasm) { auto_selected = 1; auto_space = rd_eval_space_from_ctrl_entity(ctrl_entity_from_handle(d_state->ctrl_entity_store, dv->temp_look_process), RD_EvalSpaceKind_CtrlEntity); - eval = e_eval_from_stringf(scratch.arena, "(0x%I64x & (~(0x4000 - 1)))", dv->temp_look_vaddr); + eval = e_eval_from_stringf("(0x%I64x & (~(0x4000 - 1)))", dv->temp_look_vaddr); } else { auto_selected = 1; auto_space = rd_eval_space_from_ctrl_entity(ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process), RD_EvalSpaceKind_CtrlEntity); - eval = e_eval_from_stringf(scratch.arena, "(rip.u64 & (~(0x4000 - 1)))"); + eval = e_eval_from_stringf("(rip.u64 & (~(0x4000 - 1)))"); } } @@ -2655,10 +2650,10 @@ RD_VIEW_UI_FUNCTION_DEF(memory) ui_color_from_name(str8_lit("code_local")), }; U64 thread_rip_vaddr = d_query_cached_rip_from_thread_unwind(thread, rd_regs()->unwind_count); - for(E_String2NumMapNode *n = e_ir_state->ctx->locals_map->first; n != 0; n = n->order_next) + for(E_String2NumMapNode *n = e_ir_ctx->locals_map->first; n != 0; n = n->order_next) { String8 local_name = n->string; - E_Eval local_eval = e_eval_from_string(scratch.arena, local_name); + E_Eval local_eval = e_eval_from_string(local_name); if(local_eval.irtree.mode == E_Mode_Offset) { E_TypeKind local_eval_type_kind = e_type_kind_from_key(local_eval.irtree.type_key); @@ -3463,20 +3458,20 @@ rd_eval_color_from_eval(E_Eval eval) // rjf: leaf u32 -> take all 4 components case E_TypeKind_U32: { - component_evals[0] = e_value_eval_from_eval(e_eval_wrapf(scratch.arena, t->eval, "(float32)(($ & 0xff000000) >> 24) / 255.f")); - component_evals[1] = e_value_eval_from_eval(e_eval_wrapf(scratch.arena, t->eval, "(float32)(($ & 0x00ff0000) >> 16) / 255.f")); - component_evals[2] = e_value_eval_from_eval(e_eval_wrapf(scratch.arena, t->eval, "(float32)(($ & 0x0000ff00) >> 8) / 255.f")); - component_evals[3] = e_value_eval_from_eval(e_eval_wrapf(scratch.arena, t->eval, "(float32)(($ & 0x000000ff) >> 0) / 255.f")); + component_evals[0] = e_value_eval_from_eval(e_eval_wrapf(t->eval, "(float32)(($ & 0xff000000) >> 24) / 255.f")); + component_evals[1] = e_value_eval_from_eval(e_eval_wrapf(t->eval, "(float32)(($ & 0x00ff0000) >> 16) / 255.f")); + component_evals[2] = e_value_eval_from_eval(e_eval_wrapf(t->eval, "(float32)(($ & 0x0000ff00) >> 8) / 255.f")); + component_evals[3] = e_value_eval_from_eval(e_eval_wrapf(t->eval, "(float32)(($ & 0x000000ff) >> 0) / 255.f")); num_components_left -= 4; }break; //- rjf: array -> generate tasks for first four elements case E_TypeKind_Array: { - component_evals[0] = e_value_eval_from_eval(e_eval_wrapf(scratch.arena, t->eval, "(float32)($[0])")); - component_evals[1] = e_value_eval_from_eval(e_eval_wrapf(scratch.arena, t->eval, "(float32)($[1])")); - component_evals[2] = e_value_eval_from_eval(e_eval_wrapf(scratch.arena, t->eval, "(float32)($[2])")); - component_evals[3] = e_value_eval_from_eval(e_eval_wrapf(scratch.arena, t->eval, "(float32)($[3])")); + component_evals[0] = e_value_eval_from_eval(e_eval_wrapf(t->eval, "(float32)($[0])")); + component_evals[1] = e_value_eval_from_eval(e_eval_wrapf(t->eval, "(float32)($[1])")); + component_evals[2] = e_value_eval_from_eval(e_eval_wrapf(t->eval, "(float32)($[2])")); + component_evals[3] = e_value_eval_from_eval(e_eval_wrapf(t->eval, "(float32)($[3])")); num_components_left -= 4; }break; } diff --git a/src/raddbg/raddbg_widgets.c b/src/raddbg/raddbg_widgets.c index 27ca3d96..3fd8a761 100644 --- a/src/raddbg/raddbg_widgets.c +++ b/src/raddbg/raddbg_widgets.c @@ -1983,7 +1983,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe { RD_Cfg *pin = n->v; String8 pin_expr = rd_expr_from_cfg(pin); - E_Eval eval = e_eval_from_string(scratch.arena, pin_expr); + E_Eval eval = e_eval_from_string(pin_expr); String8 eval_string = {0}; if(!e_type_key_match(e_type_key_zero(), eval.irtree.type_key)) { @@ -2327,7 +2327,7 @@ rd_code_slice(RD_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *prefe // if(!ui_dragging(text_container_sig) && text_container_sig.event_flags == 0 && mouse_expr.size != 0) { - E_Eval eval = e_eval_from_string(scratch.arena, mouse_expr); + E_Eval eval = e_eval_from_string(mouse_expr); if(eval.msgs.max_kind == E_MsgKind_Null && (eval.irtree.mode != E_Mode_Null || mouse_expr_is_explicit)) { U64 line_vaddr = 0;