Beispiel #1
0
void factor_vm::dispatch_signal(void *uap, void (handler)())
{
	UAP_STACK_POINTER(uap) = (UAP_STACK_POINTER_TYPE)fix_callstack_top((stack_frame *)UAP_STACK_POINTER(uap));
	UAP_PROGRAM_COUNTER(uap) = (cell)handler;

	ctx->callstack_top = (stack_frame *)UAP_STACK_POINTER(uap);
}
Beispiel #2
0
void throw_error(cell error, stack_frame *callstack_top)
{
	/* If the error handler is set, we rewind any C stack frames and
	pass the error to user-space. */
	if(userenv[BREAK_ENV] != F)
	{
		/* If error was thrown during heap scan, we re-enable the GC */
		gc_off = false;

		/* Reset local roots */
		gc_locals = gc_locals_region->start - sizeof(cell);
		gc_bignums = gc_bignums_region->start - sizeof(cell);

		/* If we had an underflow or overflow, stack pointers might be
		out of bounds */
		fix_stacks();

		dpush(error);

		/* Errors thrown from C code pass NULL for this parameter.
		Errors thrown from Factor code, or signal handlers, pass the
		actual stack pointer at the time, since the saved pointer is
		not necessarily up to date at that point. */
		if(callstack_top)
		{
			callstack_top = fix_callstack_top(callstack_top,
				stack_chain->callstack_bottom);
		}
		else
			callstack_top = stack_chain->callstack_top;

		throw_impl(userenv[BREAK_ENV],callstack_top);
	}
	/* Error was thrown in early startup before error handler is set, just
	crash. */
	else
	{
		print_string("You have triggered a bug in Factor. Please report.\n");
		print_string("early_error: ");
		print_obj(error);
		nl();
		factorbug();
	}
}
Beispiel #3
0
void factor_vm::throw_error(cell error, stack_frame *callstack_top)
{
    /* If the error handler is set, we rewind any C stack frames and
    pass the error to user-space. */
    if(!current_gc && to_boolean(special_objects[OBJ_BREAK]))
    {
        /* If error was thrown during heap scan, we re-enable the GC */
        gc_off = false;

        /* Reset local roots */
        data_roots.clear();
        bignum_roots.clear();
        code_roots.clear();

        /* If we had an underflow or overflow, stack pointers might be
        out of bounds */
        fix_stacks();

        dpush(error);

        /* Errors thrown from C code pass NULL for this parameter.
        Errors thrown from Factor code, or signal handlers, pass the
        actual stack pointer at the time, since the saved pointer is
        not necessarily up to date at that point. */
        if(callstack_top)
            callstack_top = fix_callstack_top(callstack_top,ctx->callstack_bottom);
        else
            callstack_top = ctx->callstack_top;

        throw_impl(special_objects[OBJ_BREAK],callstack_top,this);
    }
    /* Error was thrown in early startup before error handler is set, just
    crash. */
    else
    {
        std::cout << "You have triggered a bug in Factor. Please report.\n";
        std::cout << "early_error: ";
        print_obj(error);
        std::cout << std::endl;
        factorbug();
    }
}
Beispiel #4
0
LONG factor_vm::exception_handler(PEXCEPTION_RECORD e, void *frame, PCONTEXT c, void *dispatch)
{
	c->ESP = (cell)fix_callstack_top((stack_frame *)c->ESP);
	ctx->callstack_top = (stack_frame *)c->ESP;

	switch (e->ExceptionCode)
	{
	case EXCEPTION_ACCESS_VIOLATION:
		signal_fault_addr = e->ExceptionInformation[1];
		c->EIP = (cell)factor::memory_signal_handler_impl;
		break;

	case STATUS_FLOAT_DENORMAL_OPERAND:
	case STATUS_FLOAT_DIVIDE_BY_ZERO:
	case STATUS_FLOAT_INEXACT_RESULT:
	case STATUS_FLOAT_INVALID_OPERATION:
	case STATUS_FLOAT_OVERFLOW:
	case STATUS_FLOAT_STACK_CHECK:
	case STATUS_FLOAT_UNDERFLOW:
	case STATUS_FLOAT_MULTIPLE_FAULTS:
	case STATUS_FLOAT_MULTIPLE_TRAPS:
#ifdef FACTOR_64
		signal_fpu_status = fpu_status(MXCSR(c));
#else
		signal_fpu_status = fpu_status(X87SW(c) | MXCSR(c));

		/* This seems to have no effect */
		X87SW(c) = 0;
#endif
		MXCSR(c) &= 0xffffffc0;
		c->EIP = (cell)factor::fp_signal_handler_impl;
		break;
	default:
		signal_number = e->ExceptionCode;
		c->EIP = (cell)factor::misc_signal_handler_impl;
		break;
	}

	return 0;
}