src/exceptions.c - Exceptions


Define the internal interpreter exceptions.

Functions ^

void internal_exception(int exitcode, const char *format, ...)

Signal a fatal exception. This involves printing an error message to stderr, and calling Parrot_exit to invoke exit handlers and exit the process with the given exitcode. No error handlers are used, so it is not possible for Parrot bytecode to intercept a fatal error (cf. real_exception). Furthermore, no stack unwinding is done, so the exit handlers run in the current dynamic environment.

void do_panic(Interp *interp, const char *message, const char *file, int line)

Panic handler.

void push_exception(Interp *interp, PMC *handler)

Add the exception handler on the stack.

void Parrot_push_action(Interp *interp, PMC *sub)

Push an action handler onto the dynamic environment.

void Parrot_push_mark(Interp *interp, INTVAL mark)

Push a cleanup mark onto the dynamic environment.

void Parrot_pop_mark(Interp *interp, INTVAL mark)

Pop items off the dynamic environment up to the mark.

static PMC *find_exception_handler(Interp *interp, PMC *exception)

Find the exception handler for exception.

void pop_exception(Interp *interp)

Pops the topmost exception handler off the stack.

PMC *new_c_exception_handler(Interp *interp, Parrot_exception *jb)

Generate an exception handler, that catches PASM level exceptions inside a C function. This could be a separate class too, for now just a private flag bit is set.

void push_new_c_exception_handler(Interp *interp, Parrot_exception *jb)

Pushes an new C exception handler onto the stack.

void *throw_exception(Interp *interp, PMC *exception, void *dest)

Throw the exception.

void *rethrow_exception(Interp *interp, PMC *exception)

Rethrow the exception.

void rethrow_c_exception(Interp *interp)

Return back to runloop, assumes exception is still in TODO and that this is called from within a handler setup with new_c_exception.

static size_t dest2offset(Interp *interp, const opcode_t *dest)

Translate an absolute bytecode location to an offset used for resuming after an exception had occurred.

static opcode_t *create_exception(Interp *interp)

Create an exception.

size_t handle_exception(Interp *interp)

Handle an exception.

void new_internal_exception(Interp *interp)

Create a new internal exception buffer, either by allocating it or by getting one from the free list.

void free_internal_exception(Interp *interp)

Place internal exception buffer back on the free list.

void do_exception(Interp *interp, exception_severity severity, long error)

Called from interrupt code. Does a longjmp in front of the runloop, which calls handle_exception(), returning the handler address where execution then resumes.

void real_exception(Interp *interp, void *ret_addr, int exitcode, const char *format, ...)

Throws a real exception, with an error message constructed from the format string and arguments. ret_addr is the address from which to resume, if some handler decides that is appropriate, or zero to make the error non-resumable. exitcode is a exception_type_enum value.

See also internal_exception(), which signals fatal errors, and throw_exception, which calls the handler.

void Parrot_init_exceptions(Interp *interp)

Create exception objects.


void Parrot_init_exceptions(Interp *interp) { int i;

    interp->exception_list = mem_sys_allocate(
            sizeof (PMC*) * (E_LAST_PYTHON_E + 1));
    for (i = 0; i <= E_LAST_PYTHON_E; ++i) {
        PMC * const ex = pmc_new(interp, enum_class_Exception);
        interp->exception_list[i] = ex;
        VTABLE_set_integer_keyed_int(interp, ex, 1, i);