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
parent
fdcc33acee
commit
655dcee2d8
|
@ -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;
|
||||
|
|
|
@ -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],
|
||||
|
|
Loading…
Reference in New Issue