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