checkpoint on eval2 compiler; setting to disable update checking; cache version check to once per day so that we do not send a lot of extra GH requests every time the debugger starts

This commit is contained in:
Ryan Fleury
2026-06-16 14:30:13 -07:00
parent bcdc6acd0e
commit 00da627293
11 changed files with 530 additions and 391 deletions
+1 -1
View File
@@ -49,7 +49,7 @@ commands =
// .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, // .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
// .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg debug telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, // .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg debug telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
// .f1 = { .win = "raddbg_stable --ipc kill_all && build radbin", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, // .f1 = { .win = "raddbg_stable --ipc kill_all && build radbin", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
.f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, .f1 = { .win = "raddbg_stable --ipc kill_all && build ryan_scratch", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
//- rjf: [raddbg wsl] //- rjf: [raddbg wsl]
// .f1 = { .win = "wsl ./build.sh raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, // .f1 = { .win = "wsl ./build.sh raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
+7 -2
View File
@@ -1,4 +1,4 @@
// raddbg 0.9.27 project file // raddbg 0.9.28 project file
name: "The RAD Debugger" name: "The RAD Debugger"
target: target:
@@ -7,7 +7,6 @@ target:
working_directory: "../raddebugger" working_directory: "../raddebugger"
arguments: "--user:C:/devel/raddebugger/build/raddbg_test.user" arguments: "--user:C:/devel/raddebugger/build/raddbg_test.user"
debug_subprocesses: 0 debug_subprocesses: 0
enabled: 1
} }
target: target:
{ {
@@ -31,3 +30,9 @@ target:
working_directory: build working_directory: build
arguments: "--rdi raddbg" arguments: "--rdi raddbg"
} }
target:
{
executable: "build/ryan_scratch.exe"
working_directory: "build/"
enabled: 1
}
+42 -38
View File
@@ -49,44 +49,6 @@ arch_reg_code_from_name(ARCH_Info *arch_info, String8 name)
return result; return result;
} }
internal ARCH_RegCode
arch_reg_code_from_rdi(Arch arch, RDI_RegCode code)
{
ARCH_RegCode result = 0;
{
ARCH_Info *arch_info = arch_info_from_arch(arch);
U8 *rdi_from_reg_code_table = arch_rdi_from_reg_code_table_from_arch(arch);
for EachIndex(c, arch_info->reg_code_count)
{
if(rdi_from_reg_code_table[c] == code)
{
result = c;
break;
}
}
}
return result;
}
internal ARCH_RegCode
arch_reg_code_from_dw(Arch arch, DW_RegCode code)
{
ARCH_RegCode result = 0;
{
ARCH_Info *arch_info = arch_info_from_arch(arch);
U8 *dw_from_reg_code_table = arch_dw_from_reg_code_table_from_arch(arch);
for EachIndex(c, arch_info->reg_code_count)
{
if(dw_from_reg_code_table[c] == code)
{
result = c;
break;
}
}
}
return result;
}
internal B32 internal B32
arch_reg_block_read_range(ARCH_Info *arch_info, void *block, Rng1U16 range, void *dst) arch_reg_block_read_range(ARCH_Info *arch_info, void *block, Rng1U16 range, void *dst)
{ {
@@ -168,3 +130,45 @@ arch_reg_block_write_sp(ARCH_Info *arch_info, void *block, U64 sp)
} }
return result; return result;
} }
#if defined(RDI_H)
internal ARCH_RegCode
arch_reg_code_from_rdi(Arch arch, RDI_RegCode code)
{
ARCH_RegCode result = 0;
{
ARCH_Info *arch_info = arch_info_from_arch(arch);
U8 *rdi_from_reg_code_table = arch_rdi_from_reg_code_table_from_arch(arch);
for EachIndex(c, arch_info->reg_code_count)
{
if(rdi_from_reg_code_table[c] == code)
{
result = c;
break;
}
}
}
return result;
}
#endif
#if defined(DWARF_H)
internal ARCH_RegCode
arch_reg_code_from_dw(Arch arch, DW_RegCode code)
{
ARCH_RegCode result = 0;
{
ARCH_Info *arch_info = arch_info_from_arch(arch);
U8 *dw_from_reg_code_table = arch_dw_from_reg_code_table_from_arch(arch);
for EachIndex(c, arch_info->reg_code_count)
{
if(dw_from_reg_code_table[c] == code)
{
result = c;
break;
}
}
}
return result;
}
#endif
+7 -2
View File
@@ -37,8 +37,6 @@ global read_only ARCH_Info arch_info_nil = {0, 0, 0, 0, {0}, &arch_reg_code_rng_
internal ARCH_Info *arch_info_from_arch(Arch arch); internal ARCH_Info *arch_info_from_arch(Arch arch);
internal ARCH_RegCode arch_reg_code_from_name(ARCH_Info *arch_info, String8 name); internal ARCH_RegCode arch_reg_code_from_name(ARCH_Info *arch_info, String8 name);
internal ARCH_RegCode arch_reg_code_from_rdi(Arch arch, RDI_RegCode code);
internal ARCH_RegCode arch_reg_code_from_dw(Arch arch, DW_RegCode code);
internal B32 arch_reg_block_read_range(ARCH_Info *arch_info, void *block, Rng1U16 range, void *dst); internal B32 arch_reg_block_read_range(ARCH_Info *arch_info, void *block, Rng1U16 range, void *dst);
internal B32 arch_reg_block_write_range(ARCH_Info *arch_info, void *block, Rng1U16 range, void *src); internal B32 arch_reg_block_write_range(ARCH_Info *arch_info, void *block, Rng1U16 range, void *src);
internal U64 arch_ip_from_reg_block(ARCH_Info *arch_info, void *block); internal U64 arch_ip_from_reg_block(ARCH_Info *arch_info, void *block);
@@ -46,4 +44,11 @@ internal U64 arch_sp_from_reg_block(ARCH_Info *arch_info, void *block);
internal B32 arch_reg_block_write_ip(ARCH_Info *arch_info, void *block, U64 ip); internal B32 arch_reg_block_write_ip(ARCH_Info *arch_info, void *block, U64 ip);
internal B32 arch_reg_block_write_sp(ARCH_Info *arch_info, void *block, U64 sp); internal B32 arch_reg_block_write_sp(ARCH_Info *arch_info, void *block, U64 sp);
#if defined(RDI_H)
internal ARCH_RegCode arch_reg_code_from_rdi(Arch arch, RDI_RegCode code);
#endif
#if defined(DWARF_H)
internal ARCH_RegCode arch_reg_code_from_dw(Arch arch, DW_RegCode code);
#endif
#endif // REGS_H #endif // REGS_H
+183 -30
View File
@@ -117,24 +117,24 @@ e2_expr_from_name(E2_ExprMap *map, String8 name)
//~ rjf: Messages //~ rjf: Messages
internal E2_Msg * internal E2_Msg *
e2_msg(Arena *arena, E2_MsgList *msgs, U64 src_off, String8 string) e2_msg(Arena *arena, E2_MsgList *msgs, Rng1U64 src_range, String8 string)
{ {
E2_Msg *msg = push_array(arena, E2_Msg, 1); E2_Msg *msg = push_array(arena, E2_Msg, 1);
SLLQueuePush(msgs->first, msgs->last, msg); SLLQueuePush(msgs->first, msgs->last, msg);
msgs->count += 1; msgs->count += 1;
msg->src_off = src_off; msg->src_range = src_range;
msg->string = str8_copy(arena, string); msg->string = str8_copy(arena, string);
return msg; return msg;
} }
internal E2_Msg * internal E2_Msg *
e2_msgf(Arena *arena, E2_MsgList *msgs, U64 src_off, char *fmt, ...) e2_msgf(Arena *arena, E2_MsgList *msgs, Rng1U64 src_range, char *fmt, ...)
{ {
Temp scratch = scratch_begin(&arena, 1); Temp scratch = scratch_begin(&arena, 1);
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
String8 string = str8fv(scratch.arena, fmt, args); String8 string = str8fv(scratch.arena, fmt, args);
E2_Msg *msg = e2_msg(arena, msgs, src_off, string); E2_Msg *msg = e2_msg(arena, msgs, src_range, string);
va_end(args); va_end(args);
scratch_end(scratch); scratch_end(scratch);
return msg; return msg;
@@ -155,7 +155,7 @@ e2_type_key_basic(E2_TypeKind kind)
//~ rjf: String -> Expression //~ rjf: String -> Expression
internal E2_Token internal E2_Token
e2_token_from_string(String8 string) e2_token_from_string_off(String8 string, U64 start_off)
{ {
E2_Token token = {E2_TokenKind_Null}; E2_Token token = {E2_TokenKind_Null};
B32 identifier_tick_mode = 0; B32 identifier_tick_mode = 0;
@@ -163,7 +163,7 @@ e2_token_from_string(String8 string)
B32 numeric_exponent = 0; B32 numeric_exponent = 0;
B32 escaped = 0; B32 escaped = 0;
B32 done = 0; B32 done = 0;
for(U64 off = 0; !done && off <= string.size; off += 1) for(U64 off = start_off; !done && off <= string.size; off += 1)
{ {
U8 next_byte = (off < string.size ? string.str[off] : 0); U8 next_byte = (off < string.size ? string.str[off] : 0);
U8 next2_byte = (off+1 < string.size ? string.str[off+1] : 0); U8 next2_byte = (off+1 < string.size ? string.str[off+1] : 0);
@@ -173,7 +173,11 @@ e2_token_from_string(String8 string)
//- rjf: no set token kind => look for starters //- rjf: no set token kind => look for starters
default: default:
{ {
if(next_byte <= 32) if(next_byte == 0)
{
done = 1;
}
else if(next_byte <= 32)
{ {
token.kind = E2_TokenKind_Whitespace; token.kind = E2_TokenKind_Whitespace;
token.range.min = token.range.max = off; token.range.min = token.range.max = off;
@@ -263,6 +267,7 @@ e2_token_from_string(String8 string)
if(numeric_exponent && (next_byte == '+' || next_byte == '-')){} if(numeric_exponent && (next_byte == '+' || next_byte == '-')){}
else if((next_byte < 'a' || 'z' < next_byte) && else if((next_byte < 'a' || 'z' < next_byte) &&
(next_byte < 'A' || 'Z' < next_byte) && (next_byte < 'A' || 'Z' < next_byte) &&
(next_byte < '0' || '9' < next_byte) &&
next_byte != '.' && next_byte != '.' &&
next_byte != ':') next_byte != ':')
{ {
@@ -323,7 +328,7 @@ e2_token_from_string(String8 string)
internal U64 internal U64
e2_read_token(String8 string, U64 off, E2_Token *token_out) e2_read_token(String8 string, U64 off, E2_Token *token_out)
{ {
E2_Token token = e2_token_from_string(str8_skip(string, off)); E2_Token token = e2_token_from_string_off(string, off);
if(token_out != 0) if(token_out != 0)
{ {
token_out[0] = token; token_out[0] = token;
@@ -344,6 +349,10 @@ e2_try_token(String8 string, E2_TokenKind kind, String8 expected_string, U64 *of
if(next_token.kind == kind && (expected_string.size == 0 || str8_match(str8_substr(string, next_token.range), expected_string, 0))) if(next_token.kind == kind && (expected_string.size == 0 || str8_match(str8_substr(string, next_token.range), expected_string, 0)))
{ {
result = 1; result = 1;
if(token_out != 0)
{
token_out[0] = next_token;
}
break; break;
} }
else if(next_token.kind != E2_TokenKind_Comment && next_token.kind != E2_TokenKind_Whitespace) else if(next_token.kind != E2_TokenKind_Comment && next_token.kind != E2_TokenKind_Whitespace)
@@ -351,7 +360,7 @@ e2_try_token(String8 string, E2_TokenKind kind, String8 expected_string, U64 *of
break; break;
} }
} }
if(result) if(result && off_out != 0)
{ {
off_out[0] = off; off_out[0] = off;
} }
@@ -368,6 +377,7 @@ e2_parse_from_string(Arena *arena, E2_ParseState *state, E2_SpaceMap *space_map,
// then it is just the result // then it is just the result
for(B32 done = 0; !done;) for(B32 done = 0; !done;)
{ {
S64 max_precedence = state->top_task ? state->top_task->max_precedence : max_S64;
E2_Expr *expr = &e2_expr_nil; E2_Expr *expr = &e2_expr_nil;
E2_Token token = {0}; E2_Token token = {0};
@@ -387,25 +397,48 @@ e2_parse_from_string(Arena *arena, E2_ParseState *state, E2_SpaceMap *space_map,
MemoryCopyStruct(task->parent, &e2_expr_nil); MemoryCopyStruct(task->parent, &e2_expr_nil);
task->expected_closer = s(")"); task->expected_closer = s(")");
task->child_count_target = 1; task->child_count_target = 1;
task->max_precedence = max_S64;
SLLStackPush(state->top_task, task); SLLStackPush(state->top_task, task);
} }
//- rjf: prefix unaries //- rjf: prefix unaries
else if(e2_try_token(string, E2_TokenKind_Symbol, s(""), &off, &token)) else if(e2_try_token(string, E2_TokenKind_Symbol, s(""), &off, &token))
{ {
E2_ParseTask *task = state->free_task; // rjf: string -> operator kind
if(task != 0) E2_OpKind op_kind = E2_OpKind_Null;
{ {
SLLStackPop(state->free_task); String8 token_string = str8_substr(string, token.range);
for EachNonZeroEnumVal(E2_OpKind, k)
{
if(e2_op_kind_info_table[k].parse_kind == E2_OpParseKind_UnaryPrefix &&
e2_op_kind_info_table[k].precedence <= max_precedence &&
str8_match(token_string, e2_op_kind_info_table[k].pre, 0))
{
op_kind = k;
break;
}
}
} }
else
// rjf: push task for operand
if(op_kind != E2_OpKind_Null)
{ {
task = push_array(arena, E2_ParseTask, 1); E2_ParseTask *task = state->free_task;
if(task != 0)
{
SLLStackPop(state->free_task);
}
else
{
task = push_array(arena, E2_ParseTask, 1);
}
task->parent = push_array(arena, E2_Expr, 1);
MemoryCopyStruct(task->parent, &e2_expr_nil);
task->child_count_target = 1;
task->op_kind = op_kind;
task->max_precedence = e2_op_kind_info_table[op_kind].precedence;
SLLStackPush(state->top_task, task);
} }
task->parent = push_array(arena, E2_Expr, 1);
MemoryCopyStruct(task->parent, &e2_expr_nil);
task->child_count_target = 1;
SLLStackPush(state->top_task, task);
} }
//- rjf: leaf identifiers //- rjf: leaf identifiers
@@ -462,7 +495,7 @@ e2_parse_from_string(Arena *arena, E2_ParseState *state, E2_SpaceMap *space_map,
case 8:{expr->op = RDI_EvalOp_ConstU512; expr->type_key = e2_type_key_basic(E2_TypeKind_U512);}break; case 8:{expr->op = RDI_EvalOp_ConstU512; expr->type_key = e2_type_key_basic(E2_TypeKind_U512);}break;
default: default:
{ {
e2_msgf(arena, &parse.msgs, token.range.min, "Invalid number of numeric portions specified (%I64u; must be 2, 4, or 8).", u64_idx); e2_msgf(arena, &parse.msgs, token.range, "Invalid number of numeric portions specified (%I64u; must be 2, 4, or 8).", u64_idx);
}break; }break;
} }
scratch_end(scratch); scratch_end(scratch);
@@ -492,29 +525,149 @@ e2_parse_from_string(Arena *arena, E2_ParseState *state, E2_SpaceMap *space_map,
} }
} }
//- rjf: attach formed expressions to task //- rjf: extend parsed expression tree with trailing binary operators
if(expr != &e2_expr_nil && state->top_task != 0) if(expr != &e2_expr_nil)
{ {
SLLQueuePush(state->top_task->parent->first, state->top_task->parent->last, expr); U64 trailing_symbol_off = off;
state->top_task->child_count += 1; if(e2_try_token(string, E2_TokenKind_Symbol, s(""), &trailing_symbol_off, &token))
if(state->top_task->child_count == state->top_task->child_count_target)
{ {
// TODO(rjf): pop task, insert to parent, or decay to result - should naturally express below block too // rjf: token string -> operator kind
E2_OpKind op_kind = E2_OpKind_Null;
{
String8 token_string = str8_substr(string, token.range);
for EachNonZeroEnumVal(E2_OpKind, k)
{
if(e2_op_kind_info_table[k].parse_kind == E2_OpParseKind_Binary &&
e2_op_kind_info_table[k].precedence <= max_precedence &&
str8_match(token_string, e2_op_kind_info_table[k].pre, 0))
{
op_kind = k;
break;
}
}
}
// rjf: non-null operator kind -> build binary expression node, push task to fill other child
if(op_kind != E2_OpKind_Null)
{
E2_ParseTask *task = state->free_task;
if(task != 0)
{
SLLStackPop(state->free_task);
}
else
{
task = push_array(arena, E2_ParseTask, 1);
}
task->parent = push_array(arena, E2_Expr, 1);
MemoryCopyStruct(task->parent, &e2_expr_nil);
SLLQueuePush_NZ(&e2_expr_nil, task->parent->first, task->parent->last, expr, next);
task->child_count = 1;
task->child_count_target = 2;
task->op_kind = op_kind;
task->max_precedence = e2_op_kind_info_table[op_kind].precedence;
SLLStackPush(state->top_task, task);
}
} }
} }
//- rjf: no task -> formed expr is result //- rjf: attach formed expressions to parent task exprs; pop tasks when they're done.
if(expr != &e2_expr_nil && state->top_task == 0) // if we have no parent task, then we just fill the result, and we're done with the parse.
if(expr != &e2_expr_nil)
{ {
parse.expr = expr; //- rjf: pop finished expressions
break; E2_Expr *finished_expr = expr;
for(;state->top_task != 0;)
{
//- rjf: add finished expression to current parent; increase task child count
E2_Expr *finished_expr_parent = state->top_task->parent;
SLLQueuePush_NZ(&e2_expr_nil, finished_expr_parent->first, finished_expr_parent->last, finished_expr, next);
state->top_task->child_count += 1;
//- rjf: task child count hits limit -> complete this child
if(state->top_task->child_count >= state->top_task->child_count_target)
{
//- rjf: release task; iterate to this finished expression next
E2_ParseTask *completed_task = state->top_task;
SLLStackPop(state->top_task);
SLLStackPush(state->free_task, completed_task);
//- rjf: finish expression with operator info, if applicable
{
E2_Expr *root = completed_task->parent;
switch(completed_task->op_kind)
{
default:{}break;
//- rjf: dereference
case E2_OpKind_Deref:
{
// rjf: unpack operand
E2_Expr *rhs = root->first;
// E2_TypeKey rhs_type_key = e2_type_key_unwrap(rhs->type_key, E2_TypeUnwrapFlag_AllDecorative & ~E2_TypeUnwrapFlag_Enums);
// E2_TypeKind rhs_type_kind = e2_type_kind_from_key(rhs_type_key);
// E2_TypeKey dereferenced_type = e2_type_key_unwrap(rhs->type_key, E2_TypeUnwrapFlag_All & ~E2_TypeUnwrapFlag_Enums);
// U64 dereferenced_type_size = e2_byte_size_from_type_key(dereferenced_type);
// rjf: collect info about malformed situations
B32 malformed = 0;
// if(dereferenced_type_size == 0 && e2_type_kind_is_ptr_or_ref(rhs_type_kind))
{
malformed = 1;
// e2_msgf(arena, &parse.msgs, src->root_range, "");
}
}break;
case E2_OpKind_Address:{}break;
case E2_OpKind_Pos:{}break;
case E2_OpKind_Neg:{}break;
case E2_OpKind_LogNot:{}break;
case E2_OpKind_BitNot:{}break;
case E2_OpKind_Mul:{}break;
case E2_OpKind_Div:{}break;
case E2_OpKind_Mod:{}break;
case E2_OpKind_Add:{}break;
case E2_OpKind_Sub:{}break;
case E2_OpKind_LShift:{}break;
case E2_OpKind_RShift:{}break;
case E2_OpKind_Less:{}break;
case E2_OpKind_LtEq:{}break;
case E2_OpKind_Grtr:{}break;
case E2_OpKind_GrEq:{}break;
case E2_OpKind_EqEq:{}break;
case E2_OpKind_NtEq:{}break;
case E2_OpKind_BitAnd:{}break;
case E2_OpKind_BitXor:{}break;
case E2_OpKind_BitOr:{}break;
case E2_OpKind_LogAnd:{}break;
case E2_OpKind_LogOr:{}break;
case E2_OpKind_Define:{}break;
}
}
//- rjf: iterate to the completed task's expression node next, to try & finish it for *its* parent
finished_expr = completed_task->parent;
}
}
//- rjf: for the last finished expression, if we do not have any further tasks,
// this is our result.
if(finished_expr != &e2_expr_nil && state->top_task == 0)
{
parse.expr = finished_expr;
if(parse.status == E2_Status_Error)
{
parse.status = E2_Status_Good;
}
break;
}
} }
} }
//- rjf: advance offset if successful //- rjf: advance offset if successful
if(parse.status == E2_Status_Good) if(parse.status == E2_Status_Good)
{ {
state->string_off += off; state->string_off = off;
} }
return parse; return parse;
} }
+7 -35
View File
@@ -205,33 +205,6 @@ struct E2_Val
typedef U64 E2_SpaceID; typedef U64 E2_SpaceID;
typedef struct E2_DbgInfo E2_DbgInfo;
struct E2_DbgInfo
{
DI_Key dbgi_key;
RDI_Parsed *rdi;
String8 name;
};
typedef struct E2_Module E2_Module;
struct E2_Module
{
E2_SpaceID space_id;
Rng1U64 addr_range;
E2_DbgInfo *dbg_info;
Arch arch;
String8 name;
};
typedef struct E2_Assets E2_Assets;
struct E2_Assets
{
E2_Module *modules;
U64 modules_count;
E2_DbgInfo *dbg_infos;
U64 dbg_infos_count;
};
//////////////////////////////// ////////////////////////////////
//~ rjf: Evaluation Contexts //~ rjf: Evaluation Contexts
@@ -298,6 +271,7 @@ struct E2_Expr
E2_Expr *first; E2_Expr *first;
E2_Expr *last; E2_Expr *last;
E2_Expr *next; E2_Expr *next;
Rng1U64 src_range;
String8 string; String8 string;
RDI_EvalOp op; RDI_EvalOp op;
E2_TypeKey type_key; E2_TypeKey type_key;
@@ -327,6 +301,8 @@ struct E2_ParseTask
E2_Expr *parent; E2_Expr *parent;
U64 child_count; U64 child_count;
U64 child_count_target; U64 child_count_target;
S64 max_precedence;
E2_OpKind op_kind;
String8 expected_closer; String8 expected_closer;
}; };
@@ -342,7 +318,7 @@ typedef struct E2_Msg E2_Msg;
struct E2_Msg struct E2_Msg
{ {
E2_Msg *next; E2_Msg *next;
U64 src_off; Rng1U64 src_range;
String8 string; String8 string;
}; };
@@ -358,10 +334,6 @@ typedef struct E2_Parse E2_Parse;
struct E2_Parse struct E2_Parse
{ {
E2_Status status; E2_Status status;
E2_SpaceID space_id;
Rng1U64 missed_read_space_addr_range;
E2_CtxID ctx_id;
E2_CtxFlags missing_ctx_flags;
String8 missed_identifier; String8 missed_identifier;
E2_Expr *expr; E2_Expr *expr;
E2_Expr *access_expr; E2_Expr *access_expr;
@@ -433,8 +405,8 @@ internal E2_Expr *e2_expr_from_name(E2_ExprMap *map, String8 name);
//////////////////////////////// ////////////////////////////////
//~ rjf: Messages //~ rjf: Messages
internal E2_Msg *e2_msg(Arena *arena, E2_MsgList *msgs, U64 src_off, String8 string); internal E2_Msg *e2_msg(Arena *arena, E2_MsgList *msgs, Rng1U64 src_range, String8 string);
internal E2_Msg *e2_msgf(Arena *arena, E2_MsgList *msgs, U64 src_off, char *fmt, ...); internal E2_Msg *e2_msgf(Arena *arena, E2_MsgList *msgs, Rng1U64 src_range, char *fmt, ...);
//////////////////////////////// ////////////////////////////////
//~ rjf: Types //~ rjf: Types
@@ -444,7 +416,7 @@ internal E2_TypeKey e2_type_key_basic(E2_TypeKind kind);
//////////////////////////////// ////////////////////////////////
//~ rjf: String -> Expression //~ rjf: String -> Expression
internal E2_Token e2_token_from_string(String8 string); internal E2_Token e2_token_from_string_off(String8 string, U64 start_off);
internal U64 e2_read_token(String8 string, U64 off, E2_Token *token_out); internal U64 e2_read_token(String8 string, U64 off, E2_Token *token_out);
internal B32 e2_try_token(String8 string, E2_TokenKind kind, String8 expected_string, U64 *off_out, E2_Token *token_out); internal B32 e2_try_token(String8 string, E2_TokenKind kind, String8 expected_string, U64 *off_out, E2_Token *token_out);
internal E2_Parse e2_parse_from_string(Arena *arena, E2_ParseState *state, E2_SpaceMap *space_map, E2_ExprMap *expr_map, String8 string); internal E2_Parse e2_parse_from_string(Arena *arena, E2_ParseState *state, E2_SpaceMap *space_map, E2_ExprMap *expr_map, String8 string);
File diff suppressed because one or more lines are too long
+4
View File
@@ -320,6 +320,10 @@ RD_VocabTable:
//- rjf: symbol server //- rjf: symbol server
@default(0) @display_name('Auto Download Debug Info') @description("Automatically tries to download missing debug info from symbol server(s).") @default(0) @display_name('Auto Download Debug Info') @description("Automatically tries to download missing debug info from symbol server(s).")
'auto_download_debug_info': bool, 'auto_download_debug_info': bool,
//- rjf: update check
@default(1) @display_name('Check For Updates') @description("Enables a small network request to check if there is a newer release version available.")
'check_for_updates': bool,
} }
``` ```
} }
+85 -52
View File
@@ -10771,14 +10771,6 @@ rd_init(CmdLine *cmdln)
{ {
rd_state->update_check_arena = arena_alloc(); rd_state->update_check_arena = arena_alloc();
rd_state->update_check_http_ring = guarded_ring_alloc(rd_state->update_check_arena, KB(8)); rd_state->update_check_http_ring = guarded_ring_alloc(rd_state->update_check_arena, KB(8));
HTTP_RequestParams p =
{
.id = 1,
.method = HTTP_Method_Get,
.url = s("https://api.github.com/repos/EpicGamesExt/raddebugger/releases/latest"),
.user_agent = s("raddebugger"),
};
http_push_request(rd_state->update_check_http_ring, &p, 0);
} }
// rjf: set up schemas // rjf: set up schemas
@@ -11183,50 +11175,6 @@ rd_frame(void)
MemoryZeroStruct(&rd_state->cmd_outputs); MemoryZeroStruct(&rd_state->cmd_outputs);
} }
//////////////////////////////
//- rjf: check for updates
//
if(!rd_state->got_update_check)
{
// rjf: pop all responses that we can
B32 done = 0;
for(HTTP_Response response = {0}; http_pop_response(rd_state->update_check_arena, rd_state->update_check_http_ring, &response, 0);)
{
str8_list_push(rd_state->update_check_arena, &rd_state->update_check_response_body_pieces, response.body);
if(!response.has_more)
{
done = 1;
}
}
// rjf: if we're done -> parse response & determine if there is a new version
if(done)
{
rd_state->got_update_check = 1;
Temp scratch = scratch_begin(0, 0);
String8 response_body = str8_list_join(rd_state->update_check_arena, &rd_state->update_check_response_body_pieces, 0);
MD_Node *root = md_tree_from_string(scratch.arena, response_body)->first;
MD_Node *html_url = md_child_from_string(root, s("html_url"), 0);
String8 newest_release_url = html_url->first->string;
U64 tag_pos = str8_find_needle(newest_release_url, 0, s("tag/v"), 0);
String8 tag_name = str8_skip(newest_release_url, tag_pos);
U64 suffix_pos = str8_find_needle(tag_name, 0, s("-"), 0);
String8 version_name = str8_prefix(tag_name, suffix_pos);
U64 release_version = version_from_str8(version_name);
U64 current_version = Version(BUILD_VERSION_MAJOR, BUILD_VERSION_MINOR, BUILD_VERSION_PATCH);
if(current_version < release_version)
{
rd_state->newer_update_available = 1;
}
guarded_ring_release(rd_state->update_check_http_ring);
arena_release(rd_state->update_check_arena);
rd_state->update_check_arena = 0;
rd_state->update_check_http_ring = 0;
MemoryZeroStruct(&rd_state->update_check_response_body_pieces);
scratch_end(scratch);
}
}
////////////////////////////// //////////////////////////////
//- rjf: iterate all tabs, touch their view-states //- rjf: iterate all tabs, touch their view-states
// //
@@ -12867,6 +12815,91 @@ rd_frame(void)
rd_state->eval_viz_base_string_flags |= EV_StringFlag_DisplayAddressUnmappedStatus; rd_state->eval_viz_base_string_flags |= EV_StringFlag_DisplayAddressUnmappedStatus;
} }
////////////////////////////
//- rjf: send update check if needed
//
if(!rd_state->sent_update_check && !rd_state->got_update_check && rd_setting_b32_from_name(s("check_for_updates")))
{
rd_state->sent_update_check = 1;
Temp scratch = scratch_begin(0, 0);
String8 cached_version_check_path = str8f(scratch.arena, "%S/raddbg/last_version_check", get_process_info()->user_program_config_data_path);
String8 cached_version_check_data = data_from_file_path(scratch.arena, cached_version_check_path);
MD_Node *root = md_tree_from_string(scratch.arena, cached_version_check_data)->first;
U64 cached_dense_time = u64_from_str8(root->string, 10);
DateTime cached_date_time = date_time_from_dense_time(cached_dense_time);
DateTime now_date_time = now_time_universal();
B32 should_rerequest = 0;
if(now_date_time.day != cached_date_time.day ||
now_date_time.month != cached_date_time.month ||
now_date_time.year != cached_date_time.year)
{
should_rerequest = 1;
}
if(should_rerequest)
{
HTTP_RequestParams p =
{
.id = 1,
.method = HTTP_Method_Get,
.url = s("https://api.github.com/repos/EpicGamesExt/raddebugger/releases/latest"),
.user_agent = s("raddebugger"),
};
http_push_request(rd_state->update_check_http_ring, &p, 0);
}
else
{
rd_state->got_update_check = 1;
rd_state->newer_update_available = (B32)u64_from_str8(root->first->string, 10);
}
scratch_end(scratch);
}
//////////////////////////////
//- rjf: check for updates
//
if(rd_state->sent_update_check && !rd_state->got_update_check)
{
// rjf: pop all responses that we can
B32 done = 0;
for(HTTP_Response response = {0}; http_pop_response(rd_state->update_check_arena, rd_state->update_check_http_ring, &response, 0);)
{
str8_list_push(rd_state->update_check_arena, &rd_state->update_check_response_body_pieces, response.body);
if(!response.has_more)
{
done = 1;
}
}
// rjf: if we're done -> parse response & determine if there is a new version
if(done)
{
rd_state->got_update_check = 1;
Temp scratch = scratch_begin(0, 0);
String8 response_body = str8_list_join(rd_state->update_check_arena, &rd_state->update_check_response_body_pieces, 0);
MD_Node *root = md_tree_from_string(scratch.arena, response_body)->first;
MD_Node *html_url = md_child_from_string(root, s("html_url"), 0);
String8 newest_release_url = html_url->first->string;
U64 tag_pos = str8_find_needle(newest_release_url, 0, s("tag/v"), 0);
String8 tag_name = str8_skip(newest_release_url, tag_pos);
U64 suffix_pos = str8_find_needle(tag_name, 0, s("-"), 0);
String8 version_name = str8_prefix(tag_name, suffix_pos);
U64 release_version = version_from_str8(version_name);
U64 current_version = Version(BUILD_VERSION_MAJOR, BUILD_VERSION_MINOR, BUILD_VERSION_PATCH);
if(current_version < release_version)
{
rd_state->newer_update_available = 1;
}
String8 cached_version_check_path = str8f(scratch.arena, "%S/raddbg/last_version_check", get_process_info()->user_program_config_data_path);
write_data_to_file_path(cached_version_check_path, str8f(scratch.arena, "%I64u: %i", dense_time_from_date_time(now_time_universal()), !!rd_state->newer_update_available));
guarded_ring_release(rd_state->update_check_http_ring);
arena_release(rd_state->update_check_arena);
rd_state->update_check_arena = 0;
rd_state->update_check_http_ring = 0;
MemoryZeroStruct(&rd_state->update_check_response_body_pieces);
scratch_end(scratch);
}
}
//////////////////////////// ////////////////////////////
//- rjf: autosave if needed //- rjf: autosave if needed
// //
+1
View File
@@ -391,6 +391,7 @@ struct RD_State
U64 frame_eval_memread_endt_us; U64 frame_eval_memread_endt_us;
// rjf: update checker // rjf: update checker
B32 sent_update_check;
B32 got_update_check; B32 got_update_check;
B32 newer_update_available; B32 newer_update_available;
Arena *update_check_arena; Arena *update_check_arena;
+13 -51
View File
@@ -12,19 +12,17 @@
//- rjf: [h] //- rjf: [h]
#include "base/base_inc.h" #include "base/base_inc.h"
#include "content/content.h" #include "x64/x64.h"
#include "artifact_cache/artifact_cache.h"
#include "file_stream/file_stream.h"
#include "rdi/rdi_local.h" #include "rdi/rdi_local.h"
#include "dbg_info/dbg_info.h" #include "arch/arch_inc.h"
#include "eval2/eval2.h"
//- rjf: [c] //- rjf: [c]
#include "base/base_inc.c" #include "base/base_inc.c"
#include "content/content.c" #include "x64/x64.c"
#include "artifact_cache/artifact_cache.c"
#include "file_stream/file_stream.c"
#include "rdi/rdi_local.c" #include "rdi/rdi_local.c"
#include "dbg_info/dbg_info.c" #include "arch/arch_inc.c"
#include "eval2/eval2.c"
//////////////////////////////// ////////////////////////////////
//~ rjf: Entry Point //~ rjf: Entry Point
@@ -32,53 +30,17 @@
internal void internal void
entry_point(CmdLine *cmdline) entry_point(CmdLine *cmdline)
{ {
local_persist char *pdb_paths[] = Temp scratch = scratch_begin(0, 0);
{ E2_ParseState state = {0};
"C:/devel/raddebugger/build/raddbg.pdb", E2_SpaceMap space_map = {0};
// #include "fn_debug_infos.inc" E2_ExprMap expr_map = {0};
};
DI_Key keys[ArrayCount(pdb_paths)] = {0};
for EachElement(idx, pdb_paths)
{
String8 path = str8_cstring(pdb_paths[idx]);
keys[idx] = di_key_from_path_timestamp(path, 0);
di_open(keys[idx]);
}
for(;;) for(;;)
{ {
Access *access = access_open(); E2_Parse parse = e2_parse_from_string(scratch.arena, &state, &space_map, &expr_map, s("!123"));
B32 got_all_rdis = 1; if(parse.status == E2_Status_Good)
U64 num_rdis_loaded = 0;
for EachElement(idx, pdb_paths)
{ {
RDI_Parsed *rdi = di_rdi_from_key(access, keys[idx], 1, 0);
if(rdi == &rdi_parsed_nil)
{
got_all_rdis = 0;
}
else
{
num_rdis_loaded += 1;
}
}
printf("\rloaded [%I64u/%I64u], %I64u active threads, %I64u active processes", num_rdis_loaded, ArrayCount(pdb_paths), di_shared->conversion_thread_count, di_shared->conversion_process_count);
access_close(access);
if(got_all_rdis)
{
Access *access = access_open();
String8 search_query = str8_lit("rd_");
DI_SearchItemArray items = di_search_item_array_from_target_query(access, RDI_SectionKind_Procedures, search_query, max_U64);
printf("\n");
printf("fuzzy searched for %.*s, found %I64u items\n", str8_varg(search_query), items.count);
access_close(access);
String8 match_query = str8_lit("rd_frame");
DI_Match match = di_match_from_string(match_query, 0, max_U64);
printf("searched for %.*s, found at %i in [%I64x:%I64x]\n", str8_varg(match_query), match.idx, match.key.u64[0], match.key.u64[1]);
break; break;
} }
} }
scratch_end(scratch);
} }