diff --git a/vm/contexts.cpp b/vm/contexts.cpp index 88d27fb484..3c657bcb62 100644 --- a/vm/contexts.cpp +++ b/vm/contexts.cpp @@ -42,6 +42,23 @@ void context::fill_stack_seg(cell top_ptr, segment* seg, cell pattern) { #endif } +vm_error_type context::address_to_error(cell addr) { + if (datastack_seg->underflow_p(addr)) + return ERROR_DATASTACK_UNDERFLOW; + if (datastack_seg->overflow_p(addr)) + return ERROR_DATASTACK_OVERFLOW; + if (retainstack_seg->underflow_p(addr)) + return ERROR_RETAINSTACK_UNDERFLOW; + if (retainstack_seg->overflow_p(addr)) + return ERROR_RETAINSTACK_OVERFLOW; + /* These are flipped because the callstack grows downwards. */ + if (callstack_seg->underflow_p(addr)) + return ERROR_CALLSTACK_OVERFLOW; + if (callstack_seg->overflow_p(addr)) + return ERROR_CALLSTACK_UNDERFLOW; + return ERROR_MEMORY; +} + void context::reset() { reset_datastack(); reset_retainstack(); diff --git a/vm/contexts.hpp b/vm/contexts.hpp index b9e04fe302..c13f3a0444 100644 --- a/vm/contexts.hpp +++ b/vm/contexts.hpp @@ -49,6 +49,7 @@ struct context { void reset(); void fix_stacks(); void fill_stack_seg(cell top_ptr, segment* seg, cell pattern); + vm_error_type address_to_error(cell addr); cell peek() { return *(cell*)datastack; } diff --git a/vm/errors.cpp b/vm/errors.cpp index 6586bd4e0b..62e30dbbb6 100644 --- a/vm/errors.cpp +++ b/vm/errors.cpp @@ -117,20 +117,10 @@ void factor_vm::verify_memory_protection_error(cell addr) { void factor_vm::memory_protection_error(cell pc, cell addr) { if (code->safepoint_p(addr)) safepoint.handle_safepoint(this, pc); - else if (ctx->datastack_seg->underflow_p(addr)) - general_error(ERROR_DATASTACK_UNDERFLOW, false_object, false_object); - else if (ctx->datastack_seg->overflow_p(addr)) - general_error(ERROR_DATASTACK_OVERFLOW, false_object, false_object); - else if (ctx->retainstack_seg->underflow_p(addr)) - general_error(ERROR_RETAINSTACK_UNDERFLOW, false_object, false_object); - else if (ctx->retainstack_seg->overflow_p(addr)) - general_error(ERROR_RETAINSTACK_OVERFLOW, false_object, false_object); - else if (ctx->callstack_seg->underflow_p(addr)) - general_error(ERROR_CALLSTACK_OVERFLOW, false_object, false_object); - else if (ctx->callstack_seg->overflow_p(addr)) - general_error(ERROR_CALLSTACK_UNDERFLOW, false_object, false_object); - else - general_error(ERROR_MEMORY, from_unsigned_cell(addr), false_object); + else { + vm_error_type type = ctx->address_to_error(addr); + general_error(type, from_unsigned_cell(addr), false_object); + } } /* Allocates memory */