Пример #1
0
/* Modify a suspended thread's thread_state so that when the thread resumes
   executing, the call frame of the current C primitive (if any) is rewound, and
   the appropriate Factor error is thrown from the top-most Factor frame. */
void factor_vm::call_fault_handler(exception_type_t exception,
                                   exception_data_type_t code,
                                   MACH_EXC_STATE_TYPE* exc_state,
                                   MACH_THREAD_STATE_TYPE* thread_state,
                                   MACH_FLOAT_STATE_TYPE* float_state) {
  cell handler = 0;

  if (exception == EXC_BAD_ACCESS) {
    signal_fault_addr = MACH_EXC_STATE_FAULT(exc_state);
    signal_fault_pc = (cell)MACH_PROGRAM_COUNTER(thread_state);
    verify_memory_protection_error(signal_fault_addr);
    handler = (cell)factor::memory_signal_handler_impl;
  } else if (exception == EXC_ARITHMETIC && code != MACH_EXC_INTEGER_DIV) {
    signal_fpu_status = fpu_status(mach_fpu_status(float_state));
    mach_clear_fpu_status(float_state);
    handler = (cell)factor::fp_signal_handler_impl;
  } else {
    switch (exception) {
      case EXC_ARITHMETIC:
        signal_number = SIGFPE;
        break;
      case EXC_BAD_INSTRUCTION:
        signal_number = SIGILL;
        break;
      default:
        signal_number = SIGABRT;
        break;
    }

    handler = (cell)factor::synchronous_signal_handler_impl;
  }

  FACTOR_ASSERT(handler != 0);

  dispatch_signal_handler((cell*)&MACH_STACK_POINTER(thread_state),
                          (cell*)&MACH_PROGRAM_COUNTER(thread_state),
                          (cell)handler);
}
Пример #2
0
inline static unsigned int uap_fpu_status(void *uap)
{
	return mach_fpu_status(UAP_FS(uap));
}