@@ -123,23 +123,21 @@ e_lookup_rule_from_string(String8 string)
123123E_LOOKUP_INFO_FUNCTION_DEF (default )
124124{
125125 E_LookupInfo lookup_info = {0 };
126- Temp scratch = scratch_begin (& arena , 1 );
127126 {
128- E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr (scratch .arena , lhs );
129- E_TypeKey lhs_type_key = e_type_unwrap (lhs_irtree .type_key );
127+ E_TypeKey lhs_type_key = e_type_unwrap (lhs -> type_key );
130128 E_TypeKind lhs_type_kind = e_type_kind_from_key (lhs_type_key );
131129 if (e_type_kind_is_pointer_or_ref (lhs_type_kind ))
132130 {
133- E_Type * type = e_type_from_key ( scratch . arena , lhs_type_key );
131+ E_Type * type = e_type_from_key__cached ( lhs_type_key );
134132 lookup_info .idxed_expr_count = type -> count ;
135- E_TypeKey direct_type_key = e_type_unwrap (e_type_direct_from_key (lhs_irtree . type_key ));
133+ E_TypeKey direct_type_key = e_type_unwrap (e_type_direct_from_key (lhs -> type_key ));
136134 E_TypeKind direct_type_kind = e_type_kind_from_key (direct_type_key );
137135 if (direct_type_kind == E_TypeKind_Struct ||
138136 direct_type_kind == E_TypeKind_Class ||
139137 direct_type_kind == E_TypeKind_Union ||
140138 direct_type_kind == E_TypeKind_Enum )
141139 {
142- E_Type * direct_type = e_type_from_key ( scratch . arena , direct_type_key );
140+ E_Type * direct_type = e_type_from_key__cached ( direct_type_key );
143141 lookup_info .named_expr_count = direct_type -> count ;
144142 }
145143 }
@@ -148,16 +146,15 @@ E_LOOKUP_INFO_FUNCTION_DEF(default)
148146 lhs_type_kind == E_TypeKind_Union ||
149147 lhs_type_kind == E_TypeKind_Enum )
150148 {
151- E_Type * lhs_type = e_type_from_key ( scratch . arena , lhs_type_key );
149+ E_Type * lhs_type = e_type_from_key__cached ( lhs_type_key );
152150 lookup_info .named_expr_count = lhs_type -> count ;
153151 }
154152 else if (lhs_type_kind == E_TypeKind_Array )
155153 {
156- E_Type * lhs_type = e_type_from_key ( scratch . arena , lhs_type_key );
154+ E_Type * lhs_type = e_type_from_key__cached ( lhs_type_key );
157155 lookup_info .idxed_expr_count = lhs_type -> count ;
158156 }
159157 }
160- scratch_end (scratch );
161158 return lookup_info ;
162159}
163160
@@ -213,7 +210,7 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(default)
213210 }
214211 if (match .kind == E_MemberKind_Null )
215212 {
216- E_Type * type = e_type_from_key ( scratch . arena , check_type_key );
213+ E_Type * type = e_type_from_key__cached ( check_type_key );
217214 if (type -> enum_vals != 0 )
218215 {
219216 String8 lookup_string = exprr -> string ;
@@ -422,7 +419,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(default)
422419 E_TypeKind struct_type_kind = E_TypeKind_Null ;
423420 if (e_type_kind_is_pointer_or_ref (lhs_type_kind ))
424421 {
425- E_Type * lhs_type = e_type_from_key ( scratch . arena , lhs_type_key );
422+ E_Type * lhs_type = e_type_from_key__cached ( lhs_type_key );
426423 if (lhs_type -> count == 1 &&
427424 (direct_type_kind == E_TypeKind_Struct ||
428425 direct_type_kind == E_TypeKind_Union ||
@@ -459,7 +456,7 @@ E_LOOKUP_RANGE_FUNCTION_DEF(default)
459456 //- rjf: struct case -> the lookup-range will return a range of members
460457 if (do_struct_range )
461458 {
462- E_Type * lhs_type = e_type_from_key ( scratch . arena , lhs_type_key );
459+ E_Type * lhs_type = e_type_from_key__cached ( lhs_type_key );
463460 Rng1U64 legal_idx_range = r1u64 (0 , lhs_type -> count );
464461 Rng1U64 read_range = intersect_1u64 (legal_idx_range , idx_range );
465462 U64 read_range_count = dim_1u64 (read_range );
@@ -667,6 +664,7 @@ internal E_IRGenRule *
667664e_irgen_rule_from_string (String8 string )
668665{
669666 E_IRGenRule * rule = & e_irgen_rule__default ;
667+ if (e_ir_ctx != 0 && e_ir_ctx -> irgen_rule_map != 0 && e_ir_ctx -> irgen_rule_map -> slots_count != 0 )
670668 {
671669 E_IRGenRuleMap * map = e_ir_ctx -> irgen_rule_map ;
672670 U64 hash = e_hash_from_string (5381 , string );
@@ -710,7 +708,7 @@ e_auto_hook_map_insert_new(Arena *arena, E_AutoHookMap *map, String8 pattern, St
710708 node -> tag_expr = e_parse_expr_from_text (arena , push_str8_copy (arena , tag_expr_string ));
711709 if (!e_type_key_match (e_type_key_zero (), type_key ))
712710 {
713- U64 hash = e_hash_from_type_key ( type_key );
711+ U64 hash = e_hash_from_string ( 5381 , str8_struct ( & type_key ) );
714712 U64 slot_idx = map -> slots_count ;
715713 SLLQueuePush_N (map -> slots [slot_idx ].first , map -> slots [slot_idx ].last , node , hash_next );
716714 }
@@ -724,14 +722,17 @@ e_auto_hook_map_insert_new(Arena *arena, E_AutoHookMap *map, String8 pattern, St
724722internal E_ExprList
725723e_auto_hook_tag_exprs_from_type_key (Arena * arena , E_TypeKey type_key )
726724{
725+ ProfBeginFunction ();
727726 E_ExprList exprs = {0 };
727+ if (e_ir_ctx != 0 )
728728 {
729729 Temp scratch = scratch_begin (& arena , 1 );
730730 E_AutoHookMap * map = e_ir_ctx -> auto_hook_map ;
731731
732732 //- rjf: gather exact-type-key-matches from the map
733+ if (map != 0 && map -> slots_count != 0 )
733734 {
734- U64 hash = e_hash_from_type_key ( type_key );
735+ U64 hash = e_hash_from_string ( 5381 , str8_struct ( & type_key ) );
735736 U64 slot_idx = hash %map -> slots_count ;
736737 for (E_AutoHookNode * n = map -> slots [slot_idx ].first ; n != 0 ; n = n -> hash_next )
737738 {
@@ -743,7 +744,7 @@ e_auto_hook_tag_exprs_from_type_key(Arena *arena, E_TypeKey type_key)
743744 }
744745
745746 //- rjf: gather fuzzy matches from all patterns in the map
746- if (map -> first_pattern != 0 )
747+ if (map != 0 && map -> first_pattern != 0 )
747748 {
748749 String8 type_string = str8_skip_chop_whitespace (e_type_string_from_key (scratch .arena , type_key ));
749750 for (E_AutoHookNode * auto_hook_node = map -> first_pattern ; auto_hook_node != 0 ; auto_hook_node = auto_hook_node -> pattern_order_next )
@@ -773,6 +774,38 @@ e_auto_hook_tag_exprs_from_type_key(Arena *arena, E_TypeKey type_key)
773774
774775 scratch_end (scratch );
775776 }
777+ ProfEnd ();
778+ return exprs ;
779+ }
780+
781+ internal E_ExprList
782+ e_auto_hook_tag_exprs_from_type_key__cached (E_TypeKey type_key )
783+ {
784+ E_ExprList exprs = {0 };
785+ if (e_ir_ctx != 0 && e_ir_ctx -> type_auto_hook_cache_map != 0 && e_ir_ctx -> type_auto_hook_cache_map -> slots_count != 0 )
786+ {
787+ U64 hash = e_hash_from_string (5381 , str8_struct (& type_key ));
788+ U64 slot_idx = hash %e_ir_ctx -> type_auto_hook_cache_map -> slots_count ;
789+ E_TypeAutoHookCacheNode * node = 0 ;
790+ for (E_TypeAutoHookCacheNode * n = e_ir_ctx -> type_auto_hook_cache_map -> slots [slot_idx ].first ;
791+ n != 0 ;
792+ n = n -> next )
793+ {
794+ if (e_type_key_match (n -> key , type_key ))
795+ {
796+ node = n ;
797+ }
798+ }
799+ if (node == 0 )
800+ {
801+ // TODO(rjf): @cfg hack!!! should not be using this arena...
802+ node = push_array (e_type_state -> arena , E_TypeAutoHookCacheNode , 1 );
803+ SLLQueuePush (e_ir_ctx -> type_auto_hook_cache_map -> slots [slot_idx ].first , e_ir_ctx -> type_auto_hook_cache_map -> slots [slot_idx ].last , node );
804+ node -> key = type_key ;
805+ node -> exprs = e_auto_hook_tag_exprs_from_type_key (e_type_state -> arena , type_key );
806+ }
807+ exprs = node -> exprs ;
808+ }
776809 return exprs ;
777810}
778811
@@ -1081,30 +1114,64 @@ E_IRGEN_FUNCTION_DEF(default)
10811114 {
10821115 default :{}break ;
10831116
1084- //- rjf: references -> just descend to sub-expr
1085- case E_ExprKind_Ref :
1086- {
1087- result = e_irtree_and_type_from_expr (arena , expr -> ref );
1088- }break ;
1089-
10901117 //- rjf: accesses
10911118 case E_ExprKind_MemberAccess :
10921119 case E_ExprKind_ArrayIndex :
10931120 {
10941121 Temp scratch = scratch_begin (& arena , 1 );
10951122 E_Expr * lhs = expr -> first ;
1123+ E_Expr * rhs = lhs -> next ;
10961124 E_IRTreeAndType lhs_irtree = e_irtree_and_type_from_expr (scratch .arena , lhs );
1097- E_Type * lhs_type = e_type_from_key (scratch .arena , lhs_irtree .type_key );
1098- String8 lookup_rule_name = expr -> string ;
1099- if (lhs_type -> kind == E_TypeKind_Set )
1125+
1126+ // rjf: determine lookup rule - first check explicitly-specified tags
1127+ E_LookupRule * lookup_rule = & e_lookup_rule__default ;
1128+ for (E_Expr * tag = lhs -> first_tag ; tag != & e_expr_nil ; tag = tag -> next )
11001129 {
1101- lookup_rule_name = lhs_type -> name ;
1130+ E_LookupRule * candidate = e_lookup_rule_from_string (tag -> string );
1131+ if (candidate != & e_lookup_rule__nil )
1132+ {
1133+ lookup_rule = candidate ;
1134+ break ;
1135+ }
1136+ }
1137+
1138+ // rjf: if the lookup rule is the default, try to (a) apply set-name hooks, or (b) apply auto-hooks
1139+ if (lookup_rule == & e_lookup_rule__default )
1140+ {
1141+ // rjf: try set name
1142+ E_Type * lhs_type = e_type_from_key__cached (lhs_irtree .type_key );
1143+ if (lhs_type -> kind == E_TypeKind_Set )
1144+ {
1145+ E_LookupRule * candidate = e_lookup_rule_from_string (lhs_type -> name );
1146+ if (candidate != & e_lookup_rule__nil )
1147+ {
1148+ lookup_rule = candidate ;
1149+ }
1150+ }
1151+
1152+ // rjf: try auto tags
1153+ if (lookup_rule == & e_lookup_rule__default )
1154+ {
1155+ E_ExprList auto_tags = e_auto_hook_tag_exprs_from_type_key__cached (lhs_irtree .type_key );
1156+ for (E_ExprNode * n = auto_tags .first ; n != 0 ; n = n -> next )
1157+ {
1158+ E_LookupRule * candidate = e_lookup_rule_from_string (n -> v -> string );
1159+ if (candidate != & e_lookup_rule__nil )
1160+ {
1161+ lookup_rule = candidate ;
1162+ break ;
1163+ }
1164+ }
1165+ }
1166+ }
1167+
1168+ // rjf: use lookup rule to actually do the access
1169+ ProfScope ("lookup via rule '%.*s'" , str8_varg (lookup_rule -> name ))
1170+ {
1171+ E_LookupInfo lookup_info = lookup_rule -> info (arena , & lhs_irtree , str8_zero ());
1172+ E_LookupAccess lookup_access = lookup_rule -> access (arena , expr -> kind , lhs , rhs , lookup_info .user_data );
1173+ result = lookup_access .irtree_and_type ;
11021174 }
1103- E_Expr * rhs = lhs -> next ;
1104- E_LookupRule * lookup_rule = e_lookup_rule_from_string (lookup_rule_name );
1105- E_LookupInfo lookup_info = lookup_rule -> info (arena , lhs , str8_zero ());
1106- E_LookupAccess lookup_access = lookup_rule -> access (arena , expr -> kind , lhs , rhs , lookup_info .user_data );
1107- result = lookup_access .irtree_and_type ;
11081175 scratch_end (scratch );
11091176 }break ;
11101177
@@ -1860,15 +1927,20 @@ E_IRGEN_FUNCTION_DEF(default)
18601927internal E_IRTreeAndType
18611928e_irtree_and_type_from_expr (Arena * arena , E_Expr * expr )
18621929{
1930+ ProfBeginFunction ();
18631931 Temp scratch = scratch_begin (& arena , 1 );
18641932 E_IRTreeAndType result = {& e_irnode_nil };
1933+ if (expr -> kind == E_ExprKind_Ref )
1934+ {
1935+ expr = expr -> ref ;
1936+ }
18651937
18661938 //- rjf: pick the ir-generation rule from explicitly-stored expressions
18671939 E_IRGenRule * explicit_irgen_rule = & e_irgen_rule__default ;
18681940 E_Expr * explicit_irgen_rule_tag = & e_expr_nil ;
18691941 for (E_Expr * tag = expr -> first_tag ; tag != & e_expr_nil ; tag = tag -> next )
18701942 {
1871- String8 name = tag -> first -> string ;
1943+ String8 name = tag -> string ;
18721944 E_IRGenRule * irgen_rule_candidate = e_irgen_rule_from_string (name );
18731945 if (irgen_rule_candidate != & e_irgen_rule__default )
18741946 {
@@ -1916,24 +1988,40 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr)
19161988 }
19171989
19181990 // rjf: do this rule's generation
1919- result = t -> rule -> irgen (arena , expr , t -> tag );
1991+ ProfScope ("irgen rule '%.*s'" , str8_varg (t -> rule -> name ))
1992+ {
1993+ result = t -> rule -> irgen (arena , expr , t -> tag );
1994+ }
19201995
19211996 // rjf: find any auto hooks according to this generation's type
19221997 {
1923- E_ExprList exprs = e_auto_hook_tag_exprs_from_type_key ( scratch . arena , result .type_key );
1998+ E_ExprList exprs = e_auto_hook_tag_exprs_from_type_key__cached ( result .type_key );
19241999 for (E_ExprNode * n = exprs .first ; n != 0 ; n = n -> next )
19252000 {
19262001 for (E_Expr * tag = n -> v ; tag != & e_expr_nil ; tag = tag -> next )
19272002 {
1928- E_IRGenRule * rule = e_irgen_rule_from_string (tag -> first -> string );
1929- if (rule == & e_irgen_rule__default ) { rule = e_irgen_rule_from_string (tag -> string ); }
1930- if (rule != & e_irgen_rule__default )
2003+ B32 tag_is_poisoned = 0 ;
2004+ U64 hash = e_hash_from_string (5381 , str8_struct (& tag ));
2005+ U64 slot_idx = hash %e_ir_ctx -> used_tag_map -> slots_count ;
2006+ for (E_UsedTagNode * n = e_ir_ctx -> used_tag_map -> slots [slot_idx ].first ; n != 0 ; n = n -> next )
19312007 {
1932- Task * task = push_array (scratch .arena , Task , 1 );
1933- SLLQueuePush (first_task , last_task , task );
1934- task -> rule = rule ;
1935- task -> tag = tag ;
1936- break ;
2008+ if (n -> tag == tag )
2009+ {
2010+ tag_is_poisoned = 1 ;
2011+ break ;
2012+ }
2013+ }
2014+ if (!tag_is_poisoned )
2015+ {
2016+ E_IRGenRule * rule = e_irgen_rule_from_string (tag -> string );
2017+ if (rule != & e_irgen_rule__default )
2018+ {
2019+ Task * task = push_array (scratch .arena , Task , 1 );
2020+ SLLQueuePush (first_task , last_task , task );
2021+ task -> rule = rule ;
2022+ task -> tag = tag ;
2023+ break ;
2024+ }
19372025 }
19382026 }
19392027 }
@@ -1959,6 +2047,7 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr)
19592047 }
19602048
19612049 scratch_end (scratch );
2050+ ProfEnd ();
19622051 return result ;
19632052}
19642053
0 commit comments