VM: clear the local roots before garbage collection in general_error()

If we got here from memory_protection_error(), then the stack pointer
has been fiddled with and the elements of these vectors, which address
stack-allocated objects, are bogus and needs to be resetted.
db4
Björn Lindqvist 2014-06-22 01:24:43 +02:00 committed by Doug Coleman
parent fdcc33acee
commit 655dcee2d8
2 changed files with 18 additions and 13 deletions

View File

@ -5,11 +5,12 @@ namespace factor {
void factor_vm::dispatch_signal_handler(cell* sp, cell* pc, cell handler) {
if (!code->seg->in_segment_p(*pc) ||
*sp < ctx->callstack_seg->start + stack_reserved) {
/* Fault came from foreign code or a callstack overflow, or we don't
have enough callstack room to try the resumable handler. Cut the
callstack down to the shallowest Factor stack frame that leaves room for
the signal handler to do its thing, and launch the handler without going
through the resumable subprimitive. */
/* Fault came from the VM, foreign code, a callstack overflow, or
we don't have enough callstack room to try the resumable
handler. Cut the callstack down to the shallowest Factor stack
frame that leaves room for the signal handler to do its thing,
and launch the handler without going through the resumable
subprimitive. */
signal_resumable = false;
void* frame_top = (void*)ctx->callstack_top;
@ -23,8 +24,8 @@ void factor_vm::dispatch_signal_handler(cell* sp, cell* pc, cell handler) {
*pc = handler;
} else {
signal_resumable = true;
// Fault came from Factor, and we've got a good callstack. Route the signal
// handler through the resumable signal handler subprimitive.
/* Fault came from Factor, and we've got a good callstack. Route
the signal handler through the resumable signal handler subprimitive. */
cell offset = *sp % 16;
signal_handler_addr = handler;
@ -43,7 +44,7 @@ void factor_vm::dispatch_signal_handler(cell* sp, cell* pc, cell handler) {
*sp = newsp;
*(cell*)newsp = *pc;
} else if (offset == 16 - sizeof(cell)) {
// Make a fake frame for the leaf procedure
/* Make a fake frame for the leaf procedure */
FACTOR_ASSERT(code->code_block_for_address(*pc) != NULL);
cell newsp = *sp - LEAF_FRAME_SIZE;

View File

@ -38,6 +38,15 @@ void out_of_memory() {
/* Allocates memory */
void factor_vm::general_error(vm_error_type error, cell arg1_, cell arg2_) {
/* If we got here from memory_protection_error(), then the stack
pointer has been fiddled with and the elements of these vectors,
which address stack-allocated objects, are bogus and needs to be
resetted. */
data_roots.clear();
bignum_roots.clear();
code_roots.clear();
data_root<object> arg1(arg1_, this);
data_root<object> arg2(arg2_, this);
@ -66,11 +75,6 @@ void factor_vm::general_error(vm_error_type error, cell arg1_, cell arg2_) {
ctx->push(error_object);
/* Reset local roots */
data_roots.clear();
bignum_roots.clear();
code_roots.clear();
/* The unwind-native-frames subprimitive will clear faulting_p
if it was successfully reached. */
unwind_native_frames(special_objects[ERROR_HANDLER_QUOT],