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) {
 | 
					void factor_vm::dispatch_signal_handler(cell* sp, cell* pc, cell handler) {
 | 
				
			||||||
  if (!code->seg->in_segment_p(*pc) ||
 | 
					  if (!code->seg->in_segment_p(*pc) ||
 | 
				
			||||||
      *sp < ctx->callstack_seg->start + stack_reserved) {
 | 
					      *sp < ctx->callstack_seg->start + stack_reserved) {
 | 
				
			||||||
    /* Fault came from foreign code or a callstack overflow, or we don't
 | 
					    /* Fault came from the VM, foreign code, a callstack overflow, or
 | 
				
			||||||
       have enough callstack room to try the resumable handler. Cut the
 | 
					       we don't have enough callstack room to try the resumable
 | 
				
			||||||
       callstack down to the shallowest Factor stack frame that leaves room for
 | 
					       handler. Cut the callstack down to the shallowest Factor stack
 | 
				
			||||||
       the signal handler to do its thing, and launch the handler without going
 | 
					       frame that leaves room for the signal handler to do its thing,
 | 
				
			||||||
       through the resumable subprimitive. */
 | 
					       and launch the handler without going through the resumable
 | 
				
			||||||
 | 
					       subprimitive. */
 | 
				
			||||||
    signal_resumable = false;
 | 
					    signal_resumable = false;
 | 
				
			||||||
    void* frame_top = (void*)ctx->callstack_top;
 | 
					    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;
 | 
					    *pc = handler;
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    signal_resumable = true;
 | 
					    signal_resumable = true;
 | 
				
			||||||
    // Fault came from Factor, and we've got a good callstack. Route the signal
 | 
					    /* Fault came from Factor, and we've got a good callstack. Route
 | 
				
			||||||
    // handler through the resumable signal handler subprimitive.
 | 
					       the signal handler through the resumable signal handler subprimitive. */
 | 
				
			||||||
    cell offset = *sp % 16;
 | 
					    cell offset = *sp % 16;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    signal_handler_addr = handler;
 | 
					    signal_handler_addr = handler;
 | 
				
			||||||
| 
						 | 
					@ -43,7 +44,7 @@ void factor_vm::dispatch_signal_handler(cell* sp, cell* pc, cell handler) {
 | 
				
			||||||
      *sp = newsp;
 | 
					      *sp = newsp;
 | 
				
			||||||
      *(cell*)newsp = *pc;
 | 
					      *(cell*)newsp = *pc;
 | 
				
			||||||
    } else if (offset == 16 - sizeof(cell)) {
 | 
					    } 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);
 | 
					      FACTOR_ASSERT(code->code_block_for_address(*pc) != NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      cell newsp = *sp - LEAF_FRAME_SIZE;
 | 
					      cell newsp = *sp - LEAF_FRAME_SIZE;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,6 +38,15 @@ void out_of_memory() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Allocates memory */
 | 
					/* Allocates memory */
 | 
				
			||||||
void factor_vm::general_error(vm_error_type error, cell arg1_, cell arg2_) {
 | 
					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> arg1(arg1_, this);
 | 
				
			||||||
  data_root<object> arg2(arg2_, 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);
 | 
					    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
 | 
					    /* The unwind-native-frames subprimitive will clear faulting_p
 | 
				
			||||||
       if it was successfully reached. */
 | 
					       if it was successfully reached. */
 | 
				
			||||||
    unwind_native_frames(special_objects[ERROR_HANDLER_QUOT],
 | 
					    unwind_native_frames(special_objects[ERROR_HANDLER_QUOT],
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue