diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index e97f1142..416ab856 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -2916,7 +2916,7 @@ ctrl_thread__run(CTRL_Msg *msg) machine.tls_base = &tls_base; eval = eval_interpret(&machine, bytecode); } - if(eval.bad_eval == 0 && eval.value.u64 == 0) + if(eval.code == EVAL_ResultCode_Good && eval.value.u64 == 0) { hit_user_bp = 0; hit_conditional_bp_but_filtered = 1; diff --git a/src/df/core/df_core.c b/src/df/core/df_core.c index 2cc202da..2ec1dfa8 100644 --- a/src/df/core/df_core.c +++ b/src/df/core/df_core.c @@ -4227,6 +4227,10 @@ df_eval_from_string(Arena *arena, DBGI_Scope *scope, DF_CtrlCtx *ctrl_ctx, EVAL_ }break; } result.errors = errors; + if(EVAL_ResultCode_Good < eval.code && eval.code < EVAL_ResultCode_COUNT) + { + eval_error(arena, &result.errors, EVAL_ErrorKind_InterpretationError, 0, eval_result_code_display_strings[eval.code]); + } } //- rjf: apply dynamic type overrides diff --git a/src/eval/eval.mdesk b/src/eval/eval.mdesk index 8e26553a..ec8f3a7f 100644 --- a/src/eval/eval.mdesk +++ b/src/eval/eval.mdesk @@ -54,6 +54,22 @@ EVAL_ExprKindTable: { LeafIdent 0 "leaf_ident" } } +@table(name display_string) +EVAL_ResultCodeTable: +{ + { Good "" } + { DivideByZero "Cannot divide by zero." } + { BadOp "Invalid operation." } + { BadOpTypes "Invalid operation types." } + { BadMemRead "Failed memory read." } + { BadRegRead "Failed register read." } + { BadFrameBase "Invalid frame base address." } + { BadModuleBase "Invalid module base address." } + { BadTLSBase "Invalid thread-local storage base address." } + { InsufficientStackSpace "Insufficient evaluation machine stack space." } + { MalformedBytecode "Malformed bytecode." } +} + @table_gen { `typedef U32 EVAL_ExprKind;`; @@ -65,6 +81,12 @@ EVAL_ExprKindTable: ``; } +@table_gen_enum EVAL_ResultCode: +{ + @expand(EVAL_ResultCodeTable a) `EVAL_ResultCode_$(a.name),`; + EVAL_ResultCode_COUNT +} + @table_gen_data(type:U8, fallback:0) eval_expr_kind_child_counts: { @@ -77,6 +99,12 @@ eval_expr_kind_strings: @expand(EVAL_ExprKindTable a) `str8_lit_comp("$(a.name)"),`; } +@table_gen_data(type:String8, fallback:`{0}`) +eval_result_code_display_strings: +{ + @expand(EVAL_ResultCodeTable a) `str8_lit_comp("$(a.display_string)"),`; +} + @table_gen_data(type:String8, fallback:`{0}`) eval_expr_op_strings: { diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index 7a1d47cf..b2031631 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -13,6 +13,7 @@ typedef enum EVAL_ErrorKind EVAL_ErrorKind_MalformedInput, EVAL_ErrorKind_MissingInfo, EVAL_ErrorKind_ResolutionFailure, + EVAL_ErrorKind_InterpretationError, EVAL_ErrorKind_COUNT } EVAL_ErrorKind; diff --git a/src/eval/eval_machine.c b/src/eval/eval_machine.c index 6afd7e12..9e1dae77 100644 --- a/src/eval/eval_machine.c +++ b/src/eval/eval_machine.c @@ -5,7 +5,8 @@ //~ allen: Eval Machine Functions internal EVAL_Result -eval_interpret(EVAL_Machine *machine, String8 bytecode){ +eval_interpret(EVAL_Machine *machine, String8 bytecode) +{ ProfBeginFunction(); EVAL_Result result = {0}; @@ -23,7 +24,7 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){ // consume opcode RADDBG_EvalOp op = (RADDBG_EvalOp)*ptr; if (op >= RADDBG_EvalOp_COUNT){ - result.bad_eval = 1; + result.code = EVAL_ResultCode_BadOp; goto done; } U8 ctrlbits = raddbg_eval_opcode_ctrlbits[op]; @@ -35,7 +36,7 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){ U32 decode_size = RADDBG_DECODEN_FROM_CTRLBITS(ctrlbits); U8 *next_ptr = ptr + decode_size; if (next_ptr > opl){ - result.bad_eval = 1; + result.code = EVAL_ResultCode_BadOp; goto done; } // TODO(allen): to improve this: @@ -55,7 +56,7 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){ { U32 pop_count = RADDBG_POPN_FROM_CTRLBITS(ctrlbits); if (pop_count > stack_count){ - result.bad_eval = 1; + result.code = EVAL_ResultCode_BadOp; goto done; } if (pop_count <= stack_count){ @@ -99,7 +100,7 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){ good_read = 1; } if (!good_read){ - result.bad_eval = 1; + result.code = EVAL_ResultCode_BadMemRead; goto done; } }break; @@ -117,7 +118,7 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){ MemoryCopy(&nval, (U8*)machine->reg_data + off, size); } else{ - result.bad_eval = 1; + result.code = EVAL_ResultCode_BadRegRead; goto done; } }break; @@ -130,7 +131,7 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){ MemoryCopy(&nval, (U8*)machine->reg_data + off, size); } else{ - result.bad_eval = 1; + result.code = EVAL_ResultCode_BadRegRead; goto done; } }break; @@ -141,7 +142,7 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){ nval.u64 = *machine->frame_base + imm; } else{ - result.bad_eval = 1; + result.code = EVAL_ResultCode_BadFrameBase; goto done; } }break; @@ -152,7 +153,7 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){ nval.u64 = *machine->module_base + imm; } else{ - result.bad_eval = 1; + result.code = EVAL_ResultCode_BadModuleBase; goto done; } }break; @@ -163,7 +164,7 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){ nval.u64 = *machine->tls_base + imm; } else{ - result.bad_eval = 1; + result.code = EVAL_ResultCode_BadTLSBase; goto done; } }break; @@ -256,20 +257,35 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){ if (svals[1].f32 != 0.f){ nval.f32 = svals[0].f32/svals[1].f32; } + else + { + result.code = EVAL_ResultCode_DivideByZero; + goto done; + } } else if (imm == RADDBG_EvalTypeGroup_F64){ if (svals[1].f64 != 0.){ nval.f64 = svals[0].f64/svals[1].f64; } + else + { + result.code = EVAL_ResultCode_DivideByZero; + goto done; + } } else if (imm == RADDBG_EvalTypeGroup_U || imm == RADDBG_EvalTypeGroup_S){ if (svals[1].u64 != 0){ nval.u64 = svals[0].u64/svals[1].u64; } + else + { + result.code = EVAL_ResultCode_DivideByZero; + goto done; + } } else{ - result.bad_eval = 1; + result.code = EVAL_ResultCode_BadOpTypes; goto done; } }break; @@ -283,7 +299,7 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){ } } else{ - result.bad_eval = 1; + result.code = EVAL_ResultCode_BadOpTypes; goto done; } }break; @@ -295,7 +311,7 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){ nval.u64 = svals[0].u64 << svals[1].u64; } else{ - result.bad_eval = 1; + result.code = EVAL_ResultCode_BadOpTypes; goto done; } }break; @@ -309,7 +325,7 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){ nval.u64 = svals[0].s64 >> svals[1].u64; } else{ - result.bad_eval = 1; + result.code = EVAL_ResultCode_BadOpTypes; goto done; } }break; @@ -321,7 +337,7 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){ nval.u64 = svals[0].u64&svals[1].u64; } else{ - result.bad_eval = 1; + result.code = EVAL_ResultCode_BadOpTypes; goto done; } }break; @@ -333,7 +349,7 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){ nval.u64 = svals[0].u64|svals[1].u64; } else{ - result.bad_eval = 1; + result.code = EVAL_ResultCode_BadOpTypes; goto done; } }break; @@ -345,7 +361,7 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){ nval.u64 = svals[0].u64^svals[1].u64; } else{ - result.bad_eval = 1; + result.code = EVAL_ResultCode_BadOpTypes; goto done; } }break; @@ -357,7 +373,7 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){ nval.u64 = ~svals[0].u64; } else{ - result.bad_eval = 1; + result.code = EVAL_ResultCode_BadOpTypes; goto done; } }break; @@ -369,7 +385,7 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){ nval.u64 = (svals[0].u64 && svals[1].u64); } else{ - result.bad_eval = 1; + result.code = EVAL_ResultCode_BadOpTypes; goto done; } }break; @@ -381,7 +397,7 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){ nval.u64 = (svals[0].u64 || svals[1].u64); } else{ - result.bad_eval = 1; + result.code = EVAL_ResultCode_BadOpTypes; goto done; } }break; @@ -393,7 +409,7 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){ nval.u64 = (!svals[0].u64); } else{ - result.bad_eval = 1; + result.code = EVAL_ResultCode_BadOpTypes; goto done; } }break; @@ -423,7 +439,7 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){ nval.u64 = (svals[0].s64 <= svals[1].s64); } else{ - result.bad_eval = 1; + result.code = EVAL_ResultCode_BadOpTypes; goto done; } }break; @@ -443,7 +459,7 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){ nval.u64 = (svals[0].s64 >= svals[1].s64); } else{ - result.bad_eval = 1; + result.code = EVAL_ResultCode_BadOpTypes; goto done; } }break; @@ -463,7 +479,7 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){ nval.u64 = (svals[0].s64 < svals[1].s64); } else{ - result.bad_eval = 1; + result.code = EVAL_ResultCode_BadOpTypes; goto done; } }break; @@ -483,7 +499,7 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){ nval.u64 = (svals[0].s64 > svals[1].s64); } else{ - result.bad_eval = 1; + result.code = EVAL_ResultCode_BadOpTypes; goto done; } }break; @@ -573,7 +589,7 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){ nval = stack[stack_count - imm - 1]; } else{ - result.bad_eval = 1; + result.code = EVAL_ResultCode_BadOp; goto done; } }break; @@ -595,7 +611,7 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){ } } else{ - result.bad_eval = 1; + result.code = EVAL_ResultCode_BadOp; goto done; } }break; @@ -610,7 +626,7 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){ stack_count += 1; } else{ - result.bad_eval = 1; + result.code = EVAL_ResultCode_InsufficientStackSpace; goto done; } } @@ -622,8 +638,8 @@ eval_interpret(EVAL_Machine *machine, String8 bytecode){ if (stack_count == 1){ result.value = stack[0]; } - else{ - result.bad_eval = 1; + else if(result.code == EVAL_ResultCode_Good){ + result.code = EVAL_ResultCode_MalformedBytecode; } scratch_end(scratch); diff --git a/src/eval/eval_machine.h b/src/eval/eval_machine.h index b520629e..12b77b2f 100644 --- a/src/eval/eval_machine.h +++ b/src/eval/eval_machine.h @@ -10,7 +10,8 @@ typedef B32 EVAL_MemoryRead(void *u, void *out, U64 addr, U64 size); typedef struct EVAL_Machine EVAL_Machine; -struct EVAL_Machine{ +struct EVAL_Machine +{ void *u; Architecture arch; EVAL_MemoryRead *memory_read; @@ -22,7 +23,8 @@ struct EVAL_Machine{ }; typedef union EVAL_Slot EVAL_Slot; -union EVAL_Slot{ +union EVAL_Slot +{ U64 u256[4]; U64 u128[2]; U64 u64; @@ -32,9 +34,10 @@ union EVAL_Slot{ }; typedef struct EVAL_Result EVAL_Result; -struct EVAL_Result{ +struct EVAL_Result +{ EVAL_Slot value; - B32 bad_eval; + EVAL_ResultCode code; }; //////////////////////////////// diff --git a/src/eval/generated/eval.meta.h b/src/eval/generated/eval.meta.h index 418412c8..c02d018d 100644 --- a/src/eval/generated/eval.meta.h +++ b/src/eval/generated/eval.meta.h @@ -6,6 +6,22 @@ #ifndef EVAL_META_H #define EVAL_META_H +typedef enum EVAL_ResultCode +{ +EVAL_ResultCode_Good, +EVAL_ResultCode_DivideByZero, +EVAL_ResultCode_BadOp, +EVAL_ResultCode_BadOpTypes, +EVAL_ResultCode_BadMemRead, +EVAL_ResultCode_BadRegRead, +EVAL_ResultCode_BadFrameBase, +EVAL_ResultCode_BadModuleBase, +EVAL_ResultCode_BadTLSBase, +EVAL_ResultCode_InsufficientStackSpace, +EVAL_ResultCode_MalformedBytecode, +EVAL_ResultCode_COUNT +} EVAL_ResultCode; + typedef U32 EVAL_ExprKind; enum { @@ -137,6 +153,21 @@ str8_lit_comp("Define"), str8_lit_comp("LeafIdent"), }; +String8 eval_result_code_display_strings[] = +{ +str8_lit_comp(""), +str8_lit_comp("Cannot divide by zero."), +str8_lit_comp("Invalid operation."), +str8_lit_comp("Invalid operation types."), +str8_lit_comp("Failed memory read."), +str8_lit_comp("Failed register read."), +str8_lit_comp("Invalid frame base address."), +str8_lit_comp("Invalid module base address."), +str8_lit_comp("Invalid thread-local storage base address."), +str8_lit_comp("Insufficient evaluation machine stack space."), +str8_lit_comp("Malformed bytecode."), +}; + String8 eval_expr_op_strings[] = { str8_lit_comp("[]"),