parameterize irtree generation path with identifier resolution rules; in most cases, we want the usual order: implicit accesses -> locals -> registers -> globals/tlocals/types/procedures -> macros; but if we are specifically evaluating a call expression tree, we want to prefer callables - in this case, macros should be prioritized.

This commit is contained in:
Ryan Fleury
2025-05-12 11:56:57 -07:00
parent 8688322a43
commit fe3cac7ac3
8 changed files with 863 additions and 753 deletions
+3 -6
View File
@@ -46,7 +46,7 @@ load_paths =
commands = commands =
{ {
//- rjf: [raddbg] //- rjf: [raddbg]
// .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
//- rjf: [textperf] //- rjf: [textperf]
// .f1 = { .win = "raddbg_stable --ipc kill_all && build no_meta telemetry textperf && raddbg_stable --ipc bring_to_front && raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, // .f1 = { .win = "raddbg_stable --ipc kill_all && build no_meta telemetry textperf && raddbg_stable --ipc bring_to_front && raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
@@ -54,13 +54,10 @@ commands =
//- rjf: [tester] //- rjf: [tester]
// .f1 = { .win = "raddbg_stable --ipc kill_all && build no_meta tester", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, // .f1 = { .win = "raddbg_stable --ipc kill_all && build no_meta tester", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
//- rjf: [ryan_scratch]
.f1 = { .win = "raddbg_stable --ipc kill_all && wsl ./build.sh raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
//- rjf: running target //- rjf: running target
// .f3 = { .win = "raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, .f3 = { .win = "raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
// .f3 = { .win = "C:/devel/raddebugger/build/raddbg.exe --capture --user:C:/devel/raddebugger/build/local_dev.raddbg_user --project:C:/devel/raddebugger/build/local_dev.raddbg_project", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, // .f3 = { .win = "C:/devel/raddebugger/build/raddbg.exe --capture --user:C:/devel/raddebugger/build/local_dev.raddbg_user --project:C:/devel/raddebugger/build/local_dev.raddbg_project", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
.f3 = { .win = "wsl_launch /mnt/c/devel/raddebugger/build/raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, // .f3 = { .win = "wsl_launch /mnt/c/devel/raddebugger/build/raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
//- rjf: local target builds //- rjf: local target builds
.build_raddbg = { .win = "build raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, .build_raddbg = { .win = "build raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
+7 -3
View File
@@ -849,7 +849,7 @@ e_irtree_from_bundle(E_CacheBundle *bundle)
bundle->flags |= E_CacheBundleFlag_IRTree; bundle->flags |= E_CacheBundleFlag_IRTree;
E_IRTreeAndType parent = e_irtree_from_key(bundle->parent_key); E_IRTreeAndType parent = e_irtree_from_key(bundle->parent_key);
E_Parse parse = e_parse_from_bundle(bundle); E_Parse parse = e_parse_from_bundle(bundle);
bundle->irtree = e_push_irtree_and_type_from_expr(e_cache->arena, &parent, 0, 0, parse.expr); bundle->irtree = e_push_irtree_and_type_from_expr(e_cache->arena, &parent, &e_default_identifier_resolution_rule, 0, 0, parse.expr);
E_MsgList msgs_copy = e_msg_list_copy(e_cache->arena, &bundle->irtree.msgs); E_MsgList msgs_copy = e_msg_list_copy(e_cache->arena, &bundle->irtree.msgs);
e_msg_list_concat_in_place(&bundle->msgs, &msgs_copy); e_msg_list_concat_in_place(&bundle->msgs, &msgs_copy);
} }
@@ -1243,8 +1243,12 @@ e_range_size_from_eval(E_Eval eval)
Temp scratch = scratch_begin(0, 0); Temp scratch = scratch_begin(0, 0);
U64 element_size = e_type_byte_size_from_key(e_type_key_unwrap(type_core, E_TypeUnwrapFlag_All)); U64 element_size = e_type_byte_size_from_key(e_type_key_unwrap(type_core, E_TypeUnwrapFlag_All));
E_TypeExpandInfo expand_info = expand_rule->info(scratch.arena, eval, str8_zero()); E_TypeExpandInfo expand_info = expand_rule->info(scratch.arena, eval, str8_zero());
result = expand_info.expr_count * element_size; U64 new_result_maybe = expand_info.expr_count * element_size;
if(new_result_maybe != 0)
{
result = new_result_maybe;
got_size = 1; got_size = 1;
}
scratch_end(scratch); scratch_end(scratch);
} }
} }
@@ -1332,7 +1336,7 @@ e_debug_log_from_expr_string(Arena *arena, String8 string)
} }
//- rjf: type //- rjf: type
E_IRTreeAndType irtree = e_push_irtree_and_type_from_expr(scratch.arena, 0, 0, 0, parse.expr); E_IRTreeAndType irtree = e_push_irtree_and_type_from_expr(scratch.arena, 0, &e_default_identifier_resolution_rule, 0, 0, parse.expr);
{ {
str8_list_pushf(scratch.arena, &strings, " type:\n"); str8_list_pushf(scratch.arena, &strings, " type:\n");
S32 indent = 2; S32 indent = 2;
+289 -258
View File
@@ -497,7 +497,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(default)
E_Expr *exprl = expr->first; E_Expr *exprl = expr->first;
E_Expr *exprr = exprl->next; E_Expr *exprr = exprl->next;
E_IRTreeAndType l = *lhs_irtree; E_IRTreeAndType l = *lhs_irtree;
E_IRTreeAndType r = e_push_irtree_and_type_from_expr(arena, overridden, 0, 1, exprr); E_IRTreeAndType r = e_push_irtree_and_type_from_expr(arena, overridden, &e_default_identifier_resolution_rule, 0, 1, exprr);
e_msg_list_concat_in_place(&result.msgs, &r.msgs); e_msg_list_concat_in_place(&result.msgs, &r.msgs);
E_TypeKey l_restype = e_type_key_unwrap(l.type_key, E_TypeUnwrapFlag_AllDecorative); 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_TypeKey r_restype = e_type_key_unwrap(r.type_key, E_TypeUnwrapFlag_AllDecorative);
@@ -588,7 +588,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(default)
} }
internal E_IRTreeAndType internal E_IRTreeAndType
e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 disallow_autohooks, B32 disallow_chained_fastpaths, E_Expr *root_expr) e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_IdentifierResolutionRule *identifier_resolution_rule, B32 disallow_autohooks, B32 disallow_chained_fastpaths, E_Expr *root_expr)
{ {
ProfBeginFunction(); ProfBeginFunction();
Temp scratch = scratch_begin(&arena, 1); Temp scratch = scratch_begin(&arena, 1);
@@ -632,7 +632,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32
{ {
// rjf: unpack left-hand-side // rjf: unpack left-hand-side
E_Expr *lhs = expr->first; E_Expr *lhs = expr->first;
E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, parent, 0, 1, lhs); E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, 0, 1, lhs);
e_msg_list_concat_in_place(&result.msgs, &lhs_irtree.msgs); e_msg_list_concat_in_place(&result.msgs, &lhs_irtree.msgs);
// rjf: try all IR trees in chain // rjf: try all IR trees in chain
@@ -715,7 +715,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32
String8 full_qualified_name = str8_list_join(scratch.arena, &parts, &(StringJoin){.sep = str8_lit(".")}); String8 full_qualified_name = str8_list_join(scratch.arena, &parts, &(StringJoin){.sep = str8_lit(".")});
E_Expr *leaf_expr_name = e_push_expr(scratch.arena, E_ExprKind_LeafIdentifier, r1u64(0, 0)); E_Expr *leaf_expr_name = e_push_expr(scratch.arena, E_ExprKind_LeafIdentifier, r1u64(0, 0));
leaf_expr_name->string = full_qualified_name; leaf_expr_name->string = full_qualified_name;
result = e_push_irtree_and_type_from_expr(arena, root_parent, disallow_autohooks, disallow_autohooks, leaf_expr_name); result = e_push_irtree_and_type_from_expr(arena, root_parent, &e_default_identifier_resolution_rule, disallow_autohooks, disallow_autohooks, leaf_expr_name);
} }
} }
}break; }break;
@@ -725,7 +725,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32
{ {
// rjf: unpack operand // rjf: unpack operand
E_Expr *r_expr = expr->first; E_Expr *r_expr = expr->first;
E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, r_expr); E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, r_expr);
e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs);
E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); 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_TypeKind r_type_kind = e_type_kind_from_key(r_type);
@@ -784,7 +784,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32
{ {
// rjf: unpack operand // rjf: unpack operand
E_Expr *r_expr = expr->first; E_Expr *r_expr = expr->first;
E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, r_expr); E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, r_expr);
e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs);
E_TypeKey r_type = r_tree.type_key; E_TypeKey r_type = r_tree.type_key;
E_TypeKey r_type_unwrapped = e_type_key_unwrap(r_type, E_TypeUnwrapFlag_AllDecorative); E_TypeKey r_type_unwrapped = e_type_key_unwrap(r_type, E_TypeUnwrapFlag_AllDecorative);
@@ -812,12 +812,12 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32
// rjf: unpack operands // rjf: unpack operands
E_Expr *cast_type_expr = expr->first; E_Expr *cast_type_expr = expr->first;
E_Expr *casted_expr = cast_type_expr->next; E_Expr *casted_expr = cast_type_expr->next;
E_IRTreeAndType cast_irtree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, cast_type_expr); E_IRTreeAndType cast_irtree = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, cast_type_expr);
e_msg_list_concat_in_place(&result.msgs, &cast_irtree.msgs); e_msg_list_concat_in_place(&result.msgs, &cast_irtree.msgs);
E_TypeKey cast_type = cast_irtree.type_key; E_TypeKey cast_type = cast_irtree.type_key;
E_TypeKind cast_type_kind = e_type_kind_from_key(cast_type); 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); 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, parent, disallow_autohooks, 1, casted_expr); E_IRTreeAndType casted_tree = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, casted_expr);
e_msg_list_concat_in_place(&result.msgs, &casted_tree.msgs); 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_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); E_TypeKind casted_type_kind = e_type_kind_from_key(casted_type);
@@ -872,7 +872,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32
E_Expr *r_expr = expr->first; E_Expr *r_expr = expr->first;
E_TypeKey r_type = zero_struct; E_TypeKey r_type = zero_struct;
E_Space space = r_expr->space; E_Space space = r_expr->space;
E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, 1, 1, r_expr); E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, 1, 1, r_expr);
e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs);
r_type = r_tree.type_key; r_type = r_tree.type_key;
@@ -900,7 +900,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32
{ {
// rjf: evaluate operand tree // rjf: evaluate operand tree
E_Expr *r_expr = expr->first; E_Expr *r_expr = expr->first;
E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, 1, 1, r_expr); E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, 1, 1, r_expr);
e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs);
// rjf: fill output // rjf: fill output
@@ -914,7 +914,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32
{ {
// rjf: unpack operand // rjf: unpack operand
E_Expr *r_expr = expr->first; E_Expr *r_expr = expr->first;
E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, r_expr); E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, r_expr);
e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs);
E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); 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_TypeKind r_type_kind = e_type_kind_from_key(r_type);
@@ -942,14 +942,14 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32
//- rjf: unary operations //- rjf: unary operations
case E_ExprKind_Pos: case E_ExprKind_Pos:
{ {
result = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, expr->first); result = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, expr->first);
}break; }break;
case E_ExprKind_Neg: case E_ExprKind_Neg:
case E_ExprKind_BitNot: case E_ExprKind_BitNot:
{ {
// rjf: unpack operand // rjf: unpack operand
E_Expr *r_expr = expr->first; E_Expr *r_expr = expr->first;
E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, r_expr); E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, r_expr);
e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs);
E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); 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_TypeKind r_type_kind = e_type_kind_from_key(r_type);
@@ -982,7 +982,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32
{ {
// rjf: unpack operand // rjf: unpack operand
E_Expr *r_expr = expr->first; E_Expr *r_expr = expr->first;
E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, r_expr); E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, r_expr);
e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs);
E_TypeKey r_type = e_type_key_unwrap(r_tree.type_key, E_TypeUnwrapFlag_AllDecorative); 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_TypeKind r_type_kind = e_type_kind_from_key(r_type);
@@ -1037,8 +1037,8 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32
B32 is_comparison = e_expr_kind_is_comparison(kind); B32 is_comparison = e_expr_kind_is_comparison(kind);
E_Expr *l_expr = expr->first; E_Expr *l_expr = expr->first;
E_Expr *r_expr = l_expr->next; E_Expr *r_expr = l_expr->next;
E_IRTreeAndType l_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, l_expr); E_IRTreeAndType l_tree = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, l_expr);
E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, r_expr); E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, r_expr);
e_msg_list_concat_in_place(&result.msgs, &l_tree.msgs); e_msg_list_concat_in_place(&result.msgs, &l_tree.msgs);
e_msg_list_concat_in_place(&result.msgs, &r_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); E_TypeKey l_type = e_type_key_unwrap(l_tree.type_key, E_TypeUnwrapFlag_AllDecorative);
@@ -1279,9 +1279,9 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32
E_Expr *c_expr = expr->first; E_Expr *c_expr = expr->first;
E_Expr *l_expr = c_expr->next; E_Expr *l_expr = c_expr->next;
E_Expr *r_expr = l_expr->next; E_Expr *r_expr = l_expr->next;
E_IRTreeAndType c_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, c_expr); E_IRTreeAndType c_tree = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, c_expr);
E_IRTreeAndType l_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, l_expr); E_IRTreeAndType l_tree = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, l_expr);
E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, r_expr); E_IRTreeAndType r_tree = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, r_expr);
e_msg_list_concat_in_place(&result.msgs, &c_tree.msgs); 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, &l_tree.msgs);
e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs); e_msg_list_concat_in_place(&result.msgs, &r_tree.msgs);
@@ -1350,7 +1350,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32
{ {
B32 strip_lenses = 0; B32 strip_lenses = 0;
E_Expr *lhs = expr->first; E_Expr *lhs = expr->first;
E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, lhs); E_IRTreeAndType lhs_irtree = e_push_irtree_and_type_from_expr(arena, parent, &e_callable_identifier_resolution_rule, disallow_autohooks, 1, lhs);
e_msg_list_concat_in_place(&result.msgs, &lhs_irtree.msgs); e_msg_list_concat_in_place(&result.msgs, &lhs_irtree.msgs);
E_TypeKey lhs_type_key = lhs_irtree.type_key; E_TypeKey lhs_type_key = lhs_irtree.type_key;
E_Type *lhs_type = e_type_from_key(lhs_type_key); E_Type *lhs_type = e_type_from_key(lhs_type_key);
@@ -1358,7 +1358,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32
// rjf: calling a type? -> treat as a cast of that type // rjf: calling a type? -> treat as a cast of that type
if(lhs_irtree.mode == E_Mode_Null && lhs_type != &e_type_nil && lhs_type->kind != E_TypeKind_Lens && lhs_type->kind != E_TypeKind_LensSpec) if(lhs_irtree.mode == E_Mode_Null && lhs_type != &e_type_nil && lhs_type->kind != E_TypeKind_Lens && lhs_type->kind != E_TypeKind_LensSpec)
{ {
E_IRTreeAndType casted_tree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, expr->first->next); E_IRTreeAndType casted_tree = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, expr->first->next);
e_msg_list_concat_in_place(&result.msgs, &casted_tree.msgs); e_msg_list_concat_in_place(&result.msgs, &casted_tree.msgs);
E_TypeKey cast_type = lhs_irtree.type_key; E_TypeKey cast_type = lhs_irtree.type_key;
E_TypeKind cast_type_kind = e_type_kind_from_key(cast_type); E_TypeKind cast_type_kind = e_type_kind_from_key(cast_type);
@@ -1430,7 +1430,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32
strip_lenses = 1; strip_lenses = 1;
disallow_autohooks = 1; disallow_autohooks = 1;
} }
result = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, call); result = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, call);
// NOTE(rjf): we do not want to accumulate messages from the original left-hand-side evaluation in this case, because // NOTE(rjf): we do not want to accumulate messages from the original left-hand-side evaluation in this case, because
// this path only occurs if the member access fails specifically. // this path only occurs if the member access fails specifically.
} }
@@ -1448,7 +1448,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32
} }
// rjf: generate result via first argument to lens // rjf: generate result via first argument to lens
result = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, lhs->next); result = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, lhs->next);
// rjf: if not raw, wrap resultant type with lens type // rjf: if not raw, wrap resultant type with lens type
if(!strip_lenses) if(!strip_lenses)
@@ -1576,15 +1576,29 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32
String8 qualifier = expr->qualifier; String8 qualifier = expr->qualifier;
String8 string = expr->string; String8 string = expr->string;
String8 string__redirected = string; String8 string__redirected = string;
String8List namespaceified_strings = {0};
B32 string_mapped = 0; B32 string_mapped = 0;
B32 string_is_implicit_member_name = 0;
E_TypeKey mapped_type_key = zero_struct; E_TypeKey mapped_type_key = zero_struct;
E_Module *mapped_location_block_module = &e_module_nil; E_Module *mapped_location_block_module = &e_module_nil;
RDI_LocationBlock *mapped_location_block = 0; RDI_LocationBlock *mapped_location_block = 0;
E_Mode mapped_bytecode_mode = E_Mode_Offset; E_Mode mapped_bytecode_mode = E_Mode_Offset;
E_Space mapped_bytecode_space = zero_struct; E_Space mapped_bytecode_space = zero_struct;
String8 mapped_bytecode = {0}; String8 mapped_bytecode = {0};
B32 generated = 0;
//- rjf: iterate identifier resolution rule paths, try to resolve
// identifier in that order.
for(U64 path_idx = 0; !generated && path_idx < identifier_resolution_rule->count; path_idx += 1)
{
//- rjf: try to map identifier via this path
E_IdentifierResolutionPath path = identifier_resolution_rule->paths[path_idx];
switch(path)
{
default:{}break;
//- rjf: try to map name as parent expression signifier ('$') //- rjf: try to map name as parent expression signifier ('$')
case E_IdentifierResolutionPath_ParentExpr:
if(qualifier.size == 0 && !string_mapped && str8_match(string, str8_lit("$"), 0) && parent != 0 && (parent->root != &e_irnode_nil || parent->msgs.first != 0)) if(qualifier.size == 0 && !string_mapped && str8_match(string, str8_lit("$"), 0) && parent != 0 && (parent->root != &e_irnode_nil || parent->msgs.first != 0))
{ {
E_IRTreeAndType *parent_irtree = parent; E_IRTreeAndType *parent_irtree = parent;
@@ -1604,14 +1618,16 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32
E_MsgList msgs = e_msg_list_copy(arena, &parent_irtree->msgs); E_MsgList msgs = e_msg_list_copy(arena, &parent_irtree->msgs);
e_msg_list_concat_in_place(&result.msgs, &msgs); e_msg_list_concat_in_place(&result.msgs, &msgs);
} }
break;
//- rjf: try to map name as implicit access of overridden expression ('$.member_name', where the $. prefix is omitted) //- rjf: try to map name as implicit access of overridden expression ('$.member_name', where the $. prefix is omitted)
case E_IdentifierResolutionPath_ParentExprMember:
if(qualifier.size == 0 && !string_mapped && parent != 0 && parent->root != &e_irnode_nil) if(qualifier.size == 0 && !string_mapped && parent != 0 && parent->root != &e_irnode_nil)
{ {
for(E_IRTreeAndType *prev = parent; prev != 0; prev = prev->prev) for(E_IRTreeAndType *prev = parent; prev != 0; prev = prev->prev)
{ {
E_Expr *access = e_expr_irext_member_access(scratch.arena, &e_expr_nil, prev, string); E_Expr *access = e_expr_irext_member_access(scratch.arena, &e_expr_nil, prev, string);
E_IRTreeAndType access_irtree = e_push_irtree_and_type_from_expr(scratch.arena, prev, disallow_autohooks, 1, access); E_IRTreeAndType access_irtree = e_push_irtree_and_type_from_expr(scratch.arena, prev, &e_default_identifier_resolution_rule, disallow_autohooks, 1, access);
if(access_irtree.root != &e_irnode_nil) if(access_irtree.root != &e_irnode_nil)
{ {
string_mapped = 1; string_mapped = 1;
@@ -1623,11 +1639,11 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32
break; break;
} }
} }
} }break;
//- rjf: try to map name as member of `this` - if found, string__redirected := "this", and turn //- rjf: try to map name as member of `this` - if found, string__redirected := "this", and turn
// on later implicit-member-lookup generation // on later implicit-member-lookup generation
B32 string_is_implicit_member_name = 0; case E_IdentifierResolutionPath_ImplicitThisMember:
if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("member"), 0))) if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("member"), 0)))
{ {
E_Module *module = e_base_ctx->primary_module; E_Module *module = e_base_ctx->primary_module;
@@ -1643,9 +1659,10 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32
string_is_implicit_member_name = 1; string_is_implicit_member_name = 1;
string__redirected = str8_lit("this"); string__redirected = str8_lit("this");
} }
} }break;
//- rjf: try locals //- rjf: try locals
case E_IdentifierResolutionPath_Local:
if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("local"), 0))) if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("local"), 0)))
{ {
E_Module *module = e_base_ctx->primary_module; E_Module *module = e_base_ctx->primary_module;
@@ -1674,10 +1691,248 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32
} }
} }
} }
}break;
//- rjf: globals / procedures / types
case E_IdentifierResolutionPath_Globals:
case E_IdentifierResolutionPath_Procedures:
case E_IdentifierResolutionPath_ThreadLocals:
{
//- rjf: form namespaceified fallback versions of this lookup string
if(!string_mapped)
{
E_Module *module = e_base_ctx->primary_module;
RDI_Parsed *rdi = module->rdi;
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);
U64 last_past_scope_resolution_pos = 0;
for(;;)
{
U64 past_next_dbl_colon_pos = str8_find_needle(containing_procedure_name, last_past_scope_resolution_pos, str8_lit("::"), 0)+2;
U64 past_next_dot_pos = str8_find_needle(containing_procedure_name, last_past_scope_resolution_pos, str8_lit("."), 0)+1;
U64 past_next_scope_resolution_pos = Min(past_next_dbl_colon_pos, past_next_dot_pos);
if(past_next_scope_resolution_pos >= containing_procedure_name.size)
{
break;
}
String8 new_namespace_prefix_possibility = str8_prefix(containing_procedure_name, past_next_scope_resolution_pos);
String8 namespaceified_string = push_str8f(scratch.arena, "%S%S", new_namespace_prefix_possibility, string);
str8_list_push_front(scratch.arena, &namespaceified_strings, namespaceified_string);
last_past_scope_resolution_pos = past_next_scope_resolution_pos;
}
}
//- rjf: try globals
if(path == E_IdentifierResolutionPath_Globals && !string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("global"), 0)))
{
for(U64 module_idx = 0; module_idx < e_base_ctx->modules_count; module_idx += 1)
{
E_Module *module = &e_base_ctx->modules[module_idx];
RDI_Parsed *rdi = module->rdi;
RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_GlobalVariables);
RDI_ParsedNameMap parsed_name_map = {0};
rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map);
RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, string.str, string.size);
U32 matches_count = 0;
U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count);
for(String8Node *n = namespaceified_strings.first;
n != 0 && matches_count == 0;
n = n->next)
{
node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size);
matches_count = 0;
matches = rdi_matches_from_map_node(rdi, node, &matches_count);
}
if(matches_count != 0)
{
U32 match_idx = matches[matches_count-1];
RDI_GlobalVariable *global_var = rdi_element_from_name_idx(rdi, GlobalVariables, match_idx);
U32 type_idx = global_var->type_idx;
RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx);
E_OpList oplist = {0};
e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + global_var->voff));
string_mapped = 1;
mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx);
mapped_bytecode = e_bytecode_from_oplist(arena, &oplist);
mapped_bytecode_mode = E_Mode_Offset;
mapped_bytecode_space = module->space;
break;
}
}
}
//- rjf: try thread-locals
if(path == E_IdentifierResolutionPath_ThreadLocals && !string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("thread_local"), 0)))
{
for(U64 module_idx = 0; module_idx < e_base_ctx->modules_count; module_idx += 1)
{
E_Module *module = &e_base_ctx->modules[module_idx];
RDI_Parsed *rdi = module->rdi;
RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_ThreadVariables);
RDI_ParsedNameMap parsed_name_map = {0};
rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map);
RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, string.str, string.size);
U32 matches_count = 0;
U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count);
for(String8Node *n = namespaceified_strings.first;
n != 0 && matches_count == 0;
n = n->next)
{
node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size);
matches_count = 0;
matches = rdi_matches_from_map_node(rdi, node, &matches_count);
}
if(matches_count != 0)
{
U32 match_idx = matches[matches_count-1];
RDI_ThreadVariable *thread_var = rdi_element_from_name_idx(rdi, ThreadVariables, match_idx);
U32 type_idx = thread_var->type_idx;
RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx);
E_OpList oplist = {0};
e_oplist_push_op(arena, &oplist, RDI_EvalOp_TLSOff, e_value_u64(thread_var->tls_off));
string_mapped = 1;
mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx);
mapped_bytecode = e_bytecode_from_oplist(arena, &oplist);
mapped_bytecode_mode = E_Mode_Offset;
mapped_bytecode_space = module->space;
break;
}
}
}
//- rjf: try procedures
if(path == E_IdentifierResolutionPath_Procedures && !string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("procedure"), 0)))
{
for(U64 module_idx = 0; module_idx < e_base_ctx->modules_count; module_idx += 1)
{
E_Module *module = &e_base_ctx->modules[module_idx];
RDI_Parsed *rdi = module->rdi;
RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_Procedures);
RDI_ParsedNameMap parsed_name_map = {0};
rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map);
RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, string.str, string.size);
U32 matches_count = 0;
U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count);
for(String8Node *n = namespaceified_strings.first;
n != 0 && matches_count == 0;
n = n->next)
{
node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size);
matches_count = 0;
matches = rdi_matches_from_map_node(rdi, node, &matches_count);
}
if(matches_count != 0)
{
U32 match_idx = matches[matches_count-1];
RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, match_idx);
RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, procedure->root_scope_idx);
U64 voff = *rdi_element_from_name_idx(rdi, ScopeVOffData, scope->voff_range_first);
U32 type_idx = procedure->type_idx;
RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx);
E_OpList oplist = {0};
e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + voff));
string_mapped = 1;
mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx);
mapped_bytecode = e_bytecode_from_oplist(arena, &oplist);
mapped_bytecode_mode = E_Mode_Value;
mapped_bytecode_space = module->space;
break;
}
}
}
}break;
//- rjf: try types
case E_IdentifierResolutionPath_Types:
if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("type"), 0)))
{
mapped_type_key = e_leaf_type_from_name(string);
if(!e_type_key_match(e_type_key_zero(), mapped_type_key))
{
string_mapped = 1;
}
}break;
//- rjf: try registers
case E_IdentifierResolutionPath_Registers:
if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("reg"), 0)))
{
U64 reg_num = e_num_from_string(e_ir_ctx->regs_map, string);
if(reg_num != 0)
{
string_mapped = 1;
REGS_Rng reg_rng = regs_reg_code_rng_table_from_arch(e_base_ctx->primary_module->arch)[reg_num];
E_OpList oplist = {0};
e_oplist_push_uconst(arena, &oplist, reg_rng.byte_off);
mapped_bytecode = e_bytecode_from_oplist(arena, &oplist);
mapped_bytecode_mode = E_Mode_Offset;
mapped_bytecode_space = e_base_ctx->thread_reg_space;
mapped_type_key = e_type_key_reg(e_base_ctx->primary_module->arch, reg_num);
}
}break;
//- rjf: try register aliases
case E_IdentifierResolutionPath_RegisterAliases:
if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("reg"), 0)))
{
U64 alias_num = e_num_from_string(e_ir_ctx->reg_alias_map, string);
if(alias_num != 0)
{
string_mapped = 1;
REGS_Slice alias_slice = regs_alias_code_slice_table_from_arch(e_base_ctx->primary_module->arch)[alias_num];
REGS_Rng alias_reg_rng = regs_reg_code_rng_table_from_arch(e_base_ctx->primary_module->arch)[alias_slice.code];
E_OpList oplist = {0};
e_oplist_push_uconst(arena, &oplist, alias_reg_rng.byte_off + alias_slice.byte_off);
mapped_bytecode = e_bytecode_from_oplist(arena, &oplist);
mapped_bytecode_mode = E_Mode_Offset;
mapped_bytecode_space = e_base_ctx->thread_reg_space;
mapped_type_key = e_type_key_reg_alias(e_base_ctx->primary_module->arch, alias_num);
}
}break;
//- rjf: try basic constants
case E_IdentifierResolutionPath_Constants:
if(!string_mapped && str8_match(string, str8_lit("true"), 0))
{
string_mapped = 1;
E_OpList oplist = {0};
e_oplist_push_uconst(arena, &oplist, 1);
mapped_type_key = e_type_key_basic(E_TypeKind_Bool);
mapped_bytecode = e_bytecode_from_oplist(arena, &oplist);
mapped_bytecode_mode = E_Mode_Value;
}
if(!string_mapped && str8_match(string, str8_lit("false"), 0))
{
string_mapped = 1;
E_OpList oplist = {0};
e_oplist_push_uconst(arena, &oplist, 0);
mapped_type_key = e_type_key_basic(E_TypeKind_Bool);
mapped_bytecode = e_bytecode_from_oplist(arena, &oplist);
mapped_bytecode_mode = E_Mode_Value;
}break;
//- rjf: try macros
case E_IdentifierResolutionPath_Macros:
{
if(!generated)
{
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_ctx->macro_map, string);
result = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, macro_expr);
e_string2expr_map_dec_poison(e_ir_ctx->macro_map, string);
}
}
}break;
} }
//- rjf: mapped to location block -> extract or produce bytecode for this mapping //- rjf: mapped to location block -> extract or produce bytecode for this mapping
if(mapped_location_block != 0) if(!generated && mapped_location_block != 0)
{ {
E_Module *module = mapped_location_block_module; E_Module *module = mapped_location_block_module;
E_Space space = module->space; E_Space space = module->space;
@@ -1768,219 +2023,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32
} }
} }
//- rjf: form namespaceified fallback versions of this lookup string
String8List namespaceified_strings = {0};
if(!string_mapped)
{
E_Module *module = e_base_ctx->primary_module;
RDI_Parsed *rdi = module->rdi;
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);
U64 last_past_scope_resolution_pos = 0;
for(;;)
{
U64 past_next_dbl_colon_pos = str8_find_needle(containing_procedure_name, last_past_scope_resolution_pos, str8_lit("::"), 0)+2;
U64 past_next_dot_pos = str8_find_needle(containing_procedure_name, last_past_scope_resolution_pos, str8_lit("."), 0)+1;
U64 past_next_scope_resolution_pos = Min(past_next_dbl_colon_pos, past_next_dot_pos);
if(past_next_scope_resolution_pos >= containing_procedure_name.size)
{
break;
}
String8 new_namespace_prefix_possibility = str8_prefix(containing_procedure_name, past_next_scope_resolution_pos);
String8 namespaceified_string = push_str8f(scratch.arena, "%S%S", new_namespace_prefix_possibility, string);
str8_list_push_front(scratch.arena, &namespaceified_strings, namespaceified_string);
last_past_scope_resolution_pos = past_next_scope_resolution_pos;
}
}
//- rjf: try globals
if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("global"), 0)))
{
for(U64 module_idx = 0; module_idx < e_base_ctx->modules_count; module_idx += 1)
{
E_Module *module = &e_base_ctx->modules[module_idx];
RDI_Parsed *rdi = module->rdi;
RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_GlobalVariables);
RDI_ParsedNameMap parsed_name_map = {0};
rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map);
RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, string.str, string.size);
U32 matches_count = 0;
U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count);
for(String8Node *n = namespaceified_strings.first;
n != 0 && matches_count == 0;
n = n->next)
{
node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size);
matches_count = 0;
matches = rdi_matches_from_map_node(rdi, node, &matches_count);
}
if(matches_count != 0)
{
U32 match_idx = matches[matches_count-1];
RDI_GlobalVariable *global_var = rdi_element_from_name_idx(rdi, GlobalVariables, match_idx);
U32 type_idx = global_var->type_idx;
RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx);
E_OpList oplist = {0};
e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + global_var->voff));
string_mapped = 1;
mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx);
mapped_bytecode = e_bytecode_from_oplist(arena, &oplist);
mapped_bytecode_mode = E_Mode_Offset;
mapped_bytecode_space = module->space;
break;
}
}
}
//- rjf: try thread-locals
if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("thread_local"), 0)))
{
for(U64 module_idx = 0; module_idx < e_base_ctx->modules_count; module_idx += 1)
{
E_Module *module = &e_base_ctx->modules[module_idx];
RDI_Parsed *rdi = module->rdi;
RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_ThreadVariables);
RDI_ParsedNameMap parsed_name_map = {0};
rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map);
RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, string.str, string.size);
U32 matches_count = 0;
U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count);
for(String8Node *n = namespaceified_strings.first;
n != 0 && matches_count == 0;
n = n->next)
{
node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size);
matches_count = 0;
matches = rdi_matches_from_map_node(rdi, node, &matches_count);
}
if(matches_count != 0)
{
U32 match_idx = matches[matches_count-1];
RDI_ThreadVariable *thread_var = rdi_element_from_name_idx(rdi, ThreadVariables, match_idx);
U32 type_idx = thread_var->type_idx;
RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx);
E_OpList oplist = {0};
e_oplist_push_op(arena, &oplist, RDI_EvalOp_TLSOff, e_value_u64(thread_var->tls_off));
string_mapped = 1;
mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx);
mapped_bytecode = e_bytecode_from_oplist(arena, &oplist);
mapped_bytecode_mode = E_Mode_Offset;
mapped_bytecode_space = module->space;
break;
}
}
}
//- rjf: try procedures
if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("procedure"), 0)))
{
for(U64 module_idx = 0; module_idx < e_base_ctx->modules_count; module_idx += 1)
{
E_Module *module = &e_base_ctx->modules[module_idx];
RDI_Parsed *rdi = module->rdi;
RDI_NameMap *name_map = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_Procedures);
RDI_ParsedNameMap parsed_name_map = {0};
rdi_parsed_from_name_map(rdi, name_map, &parsed_name_map);
RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &parsed_name_map, string.str, string.size);
U32 matches_count = 0;
U32 *matches = rdi_matches_from_map_node(rdi, node, &matches_count);
for(String8Node *n = namespaceified_strings.first;
n != 0 && matches_count == 0;
n = n->next)
{
node = rdi_name_map_lookup(rdi, &parsed_name_map, n->string.str, n->string.size);
matches_count = 0;
matches = rdi_matches_from_map_node(rdi, node, &matches_count);
}
if(matches_count != 0)
{
U32 match_idx = matches[matches_count-1];
RDI_Procedure *procedure = rdi_element_from_name_idx(rdi, Procedures, match_idx);
RDI_Scope *scope = rdi_element_from_name_idx(rdi, Scopes, procedure->root_scope_idx);
U64 voff = *rdi_element_from_name_idx(rdi, ScopeVOffData, scope->voff_range_first);
U32 type_idx = procedure->type_idx;
RDI_TypeNode *type_node = rdi_element_from_name_idx(rdi, TypeNodes, type_idx);
E_OpList oplist = {0};
e_oplist_push_op(arena, &oplist, RDI_EvalOp_ConstU64, e_value_u64(module->vaddr_range.min + voff));
string_mapped = 1;
mapped_type_key = e_type_key_ext(e_type_kind_from_rdi(type_node->kind), type_idx, (U32)module_idx);
mapped_bytecode = e_bytecode_from_oplist(arena, &oplist);
mapped_bytecode_mode = E_Mode_Value;
mapped_bytecode_space = module->space;
break;
}
}
}
//- rjf: try types
if(!string_mapped && (qualifier.size == 0 || str8_match(qualifier, str8_lit("type"), 0)))
{
mapped_type_key = e_leaf_type_from_name(string);
if(!e_type_key_match(e_type_key_zero(), mapped_type_key))
{
string_mapped = 1;
}
}
//- 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_ctx->regs_map, string);
if(reg_num != 0)
{
string_mapped = 1;
REGS_Rng reg_rng = regs_reg_code_rng_table_from_arch(e_base_ctx->primary_module->arch)[reg_num];
E_OpList oplist = {0};
e_oplist_push_uconst(arena, &oplist, reg_rng.byte_off);
mapped_bytecode = e_bytecode_from_oplist(arena, &oplist);
mapped_bytecode_mode = E_Mode_Offset;
mapped_bytecode_space = e_base_ctx->thread_reg_space;
mapped_type_key = e_type_key_reg(e_base_ctx->primary_module->arch, reg_num);
}
}
//- 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_ctx->reg_alias_map, string);
if(alias_num != 0)
{
string_mapped = 1;
REGS_Slice alias_slice = regs_alias_code_slice_table_from_arch(e_base_ctx->primary_module->arch)[alias_num];
REGS_Rng alias_reg_rng = regs_reg_code_rng_table_from_arch(e_base_ctx->primary_module->arch)[alias_slice.code];
E_OpList oplist = {0};
e_oplist_push_uconst(arena, &oplist, alias_reg_rng.byte_off + alias_slice.byte_off);
mapped_bytecode = e_bytecode_from_oplist(arena, &oplist);
mapped_bytecode_mode = E_Mode_Offset;
mapped_bytecode_space = e_base_ctx->thread_reg_space;
mapped_type_key = e_type_key_reg_alias(e_base_ctx->primary_module->arch, alias_num);
}
}
//- rjf: try basic constants
if(!string_mapped && str8_match(string, str8_lit("true"), 0))
{
string_mapped = 1;
E_OpList oplist = {0};
e_oplist_push_uconst(arena, &oplist, 1);
mapped_type_key = e_type_key_basic(E_TypeKind_Bool);
mapped_bytecode = e_bytecode_from_oplist(arena, &oplist);
mapped_bytecode_mode = E_Mode_Value;
}
if(!string_mapped && str8_match(string, str8_lit("false"), 0))
{
string_mapped = 1;
E_OpList oplist = {0};
e_oplist_push_uconst(arena, &oplist, 0);
mapped_type_key = e_type_key_basic(E_TypeKind_Bool);
mapped_bytecode = e_bytecode_from_oplist(arena, &oplist);
mapped_bytecode_mode = E_Mode_Value;
}
//- rjf: generate IR trees for bytecode //- rjf: generate IR trees for bytecode
B32 generated = 0;
if(!generated && mapped_bytecode.size != 0) if(!generated && mapped_bytecode.size != 0)
{ {
generated = 1; generated = 1;
@@ -1999,25 +2042,13 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32
result.type_key = mapped_type_key; result.type_key = mapped_type_key;
result.mode = E_Mode_Null; result.mode = E_Mode_Null;
} }
//- rjf: generate IR trees for macros
if(!generated)
{
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_ctx->macro_map, string);
result = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, macro_expr);
e_string2expr_map_dec_poison(e_ir_ctx->macro_map, string);
}
} }
//- rjf: extend generated result, if result was generated by an implicit member access //- rjf: extend generated result, if result was generated by an implicit member access
if(string_is_implicit_member_name) if(generated && string_is_implicit_member_name)
{ {
E_Expr *access = e_expr_irext_member_access(arena, &e_expr_nil, &result, string); E_Expr *access = e_expr_irext_member_access(arena, &e_expr_nil, &result, string);
result = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, access); result = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, access);
} }
//- rjf: error on failure-to-generate //- rjf: error on failure-to-generate
@@ -2089,7 +2120,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32
}break; }break;
case E_ExprKind_Unsigned: case E_ExprKind_Unsigned:
{ {
E_IRTreeAndType direct_irtree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, expr->first); E_IRTreeAndType direct_irtree = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, expr->first);
result = direct_irtree; result = direct_irtree;
E_TypeKey direct_type_key = result.type_key; E_TypeKey direct_type_key = result.type_key;
E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key); E_TypeKind direct_type_kind = e_type_kind_from_key(direct_type_key);
@@ -2119,13 +2150,13 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32
}break; }break;
case E_ExprKind_Ptr: case E_ExprKind_Ptr:
{ {
E_IRTreeAndType ptee_irtree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, expr->first); E_IRTreeAndType ptee_irtree = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, expr->first);
result = ptee_irtree; result = ptee_irtree;
result.type_key = e_type_key_cons_ptr(e_base_ctx->primary_module->arch, result.type_key, 1, 0); result.type_key = e_type_key_cons_ptr(e_base_ctx->primary_module->arch, result.type_key, 1, 0);
}break; }break;
case E_ExprKind_Array: case E_ExprKind_Array:
{ {
E_IRTreeAndType element_irtree = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, expr->first); E_IRTreeAndType element_irtree = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, expr->first);
result = element_irtree; result = element_irtree;
result.type_key = e_type_key_cons_array(result.type_key, expr->value.u64, 0); result.type_key = e_type_key_cons_array(result.type_key, expr->value.u64, 0);
}break; }break;
@@ -2139,7 +2170,7 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32
{ {
E_Expr *lhs = expr->first; E_Expr *lhs = expr->first;
E_Expr *rhs = lhs->next; E_Expr *rhs = lhs->next;
result = e_push_irtree_and_type_from_expr(arena, parent, disallow_autohooks, 1, rhs); result = e_push_irtree_and_type_from_expr(arena, parent, &e_default_identifier_resolution_rule, disallow_autohooks, 1, rhs);
if(lhs->kind != E_ExprKind_LeafIdentifier) if(lhs->kind != E_ExprKind_LeafIdentifier)
{ {
e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->range, "Left side of assignment must be an unused identifier."); e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, expr->range, "Left side of assignment must be an unused identifier.");
+73 -1
View File
@@ -4,6 +4,33 @@
#ifndef EVAL_IR_H #ifndef EVAL_IR_H
#define EVAL_IR_H #define EVAL_IR_H
////////////////////////////////
//~ rjf: Identifier Resolution Rule Types
typedef enum E_IdentifierResolutionPath
{
E_IdentifierResolutionPath_ParentExpr,
E_IdentifierResolutionPath_ParentExprMember,
E_IdentifierResolutionPath_ImplicitThisMember,
E_IdentifierResolutionPath_Local,
E_IdentifierResolutionPath_Globals,
E_IdentifierResolutionPath_ThreadLocals,
E_IdentifierResolutionPath_Procedures,
E_IdentifierResolutionPath_Types,
E_IdentifierResolutionPath_Registers,
E_IdentifierResolutionPath_RegisterAliases,
E_IdentifierResolutionPath_Constants,
E_IdentifierResolutionPath_Macros,
}
E_IdentifierResolutionPath;
typedef struct E_IdentifierResolutionRule E_IdentifierResolutionRule;
struct E_IdentifierResolutionRule
{
E_IdentifierResolutionPath *paths;
U64 count;
};
//////////////////////////////// ////////////////////////////////
//~ rjf: IR State //~ rjf: IR State
@@ -49,6 +76,51 @@ struct E_IRState
E_IRCacheSlot *ir_cache_slots; E_IRCacheSlot *ir_cache_slots;
}; };
////////////////////////////////
//~ rjf: Globals
E_IdentifierResolutionPath e_default_identifier_resolution_paths[] =
{
E_IdentifierResolutionPath_ParentExpr,
E_IdentifierResolutionPath_ParentExprMember,
E_IdentifierResolutionPath_ImplicitThisMember,
E_IdentifierResolutionPath_Local,
E_IdentifierResolutionPath_Globals,
E_IdentifierResolutionPath_ThreadLocals,
E_IdentifierResolutionPath_Procedures,
E_IdentifierResolutionPath_Types,
E_IdentifierResolutionPath_Registers,
E_IdentifierResolutionPath_RegisterAliases,
E_IdentifierResolutionPath_Constants,
E_IdentifierResolutionPath_Macros,
};
E_IdentifierResolutionRule e_default_identifier_resolution_rule =
{
e_default_identifier_resolution_paths,
ArrayCount(e_default_identifier_resolution_paths),
};
E_IdentifierResolutionPath e_callable_identifier_resolution_paths[] =
{
E_IdentifierResolutionPath_Macros,
E_IdentifierResolutionPath_ParentExpr,
E_IdentifierResolutionPath_ParentExprMember,
E_IdentifierResolutionPath_ImplicitThisMember,
E_IdentifierResolutionPath_Local,
E_IdentifierResolutionPath_Globals,
E_IdentifierResolutionPath_ThreadLocals,
E_IdentifierResolutionPath_Procedures,
E_IdentifierResolutionPath_Types,
E_IdentifierResolutionPath_Registers,
E_IdentifierResolutionPath_RegisterAliases,
E_IdentifierResolutionPath_Constants,
};
E_IdentifierResolutionRule e_callable_identifier_resolution_rule =
{
e_callable_identifier_resolution_paths,
ArrayCount(e_callable_identifier_resolution_paths),
};
//////////////////////////////// ////////////////////////////////
//~ rjf: IR-ization Functions //~ rjf: IR-ization Functions
@@ -88,7 +160,7 @@ internal void e_expr_unpoison(E_Expr *expr);
//- rjf: top-level irtree/type extraction //- rjf: top-level irtree/type extraction
E_TYPE_ACCESS_FUNCTION_DEF(default); E_TYPE_ACCESS_FUNCTION_DEF(default);
internal E_IRTreeAndType e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, B32 disallow_autohooks, B32 disallow_chained_fastpaths, E_Expr *root_expr); internal E_IRTreeAndType e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_IdentifierResolutionRule *identifier_resolution_rule, B32 disallow_autohooks, B32 disallow_chained_fastpaths, E_Expr *root_expr);
//- rjf: irtree -> linear ops/bytecode //- rjf: irtree -> linear ops/bytecode
internal void e_append_oplist_from_irtree(Arena *arena, E_IRNode *root, E_Space *current_space, E_OpList *out); internal void e_append_oplist_from_irtree(Arena *arena, E_IRNode *root, E_Space *current_space, E_OpList *out);
+1 -1
View File
@@ -2661,7 +2661,7 @@ E_TYPE_ACCESS_FUNCTION_DEF(slice)
E_IRNode *idxed_base_tree = &e_irnode_nil; E_IRNode *idxed_base_tree = &e_irnode_nil;
if(base_ptr_tree != &e_irnode_nil) if(base_ptr_tree != &e_irnode_nil)
{ {
E_IRTreeAndType idx_irtree = e_push_irtree_and_type_from_expr(arena, 0, 0, 1, expr->first->next); E_IRTreeAndType idx_irtree = e_push_irtree_and_type_from_expr(arena, 0, &e_default_identifier_resolution_rule, 0, 1, expr->first->next);
E_IRNode *idx_root = e_irtree_resolve_to_value(arena, idx_irtree.mode, idx_irtree.root, idx_irtree.type_key); E_IRNode *idx_root = e_irtree_resolve_to_value(arena, idx_irtree.mode, idx_irtree.root, idx_irtree.type_key);
E_IRNode *off_root = e_irtree_binary_op_u(arena, RDI_EvalOp_Mul, idx_root, e_irtree_const_u(arena, e_type_byte_size_from_key(e_type_key_unwrap(ext->base_ptr_member->type_key, E_TypeUnwrapFlag_All)))); E_IRNode *off_root = e_irtree_binary_op_u(arena, RDI_EvalOp_Mul, idx_root, e_irtree_const_u(arena, e_type_byte_size_from_key(e_type_key_unwrap(ext->base_ptr_member->type_key, E_TypeUnwrapFlag_All))));
idxed_base_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Add, base_ptr_tree, off_root); idxed_base_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Add, base_ptr_tree, off_root);
+7 -1
View File
@@ -1952,6 +1952,12 @@ fancy_viz_eval_tests(void)
Bitmap foo = {(unsigned char *)&pixels[0], 18, 18}; Bitmap foo = {(unsigned char *)&pixels[0], 18, 18};
raddbg_pin(foo); raddbg_pin(foo);
//- rjf: name collisions with debugger rules
Function_Few_Params_Type *raw = 0;
char *text = "some_important_text_here\n";
Bitmap bitmap = foo;
int x3 = 0;
//- rjf: 3D geometry //- rjf: 3D geometry
float vertex_data[] = // pos.x, pos.y, pos.z, nor.x, nor.y, nor.z, tex.u, tex.v, col.r, col.g, col.b, ... float vertex_data[] = // pos.x, pos.y, pos.z, nor.x, nor.y, nor.z, tex.u, tex.v, col.r, col.g, col.b, ...
{ {
@@ -2143,7 +2149,7 @@ fancy_viz_eval_tests(void)
float *vtx = vertex_data; float *vtx = vertex_data;
int vtx_size = sizeof vertex_data; int vtx_size = sizeof vertex_data;
raddbg_pin(geo3d(index_data, count = count, vtx = vtx, vtx_size = vtx_size)); raddbg_pin(geo3d(index_data, count = count, vtx = vtx, vtx_size = vtx_size));
int x3 = 0; int x4 = 0;
} }
//////////////////////////////// ////////////////////////////////