/*
 * exception.h
 *
 * Copyright (C) 2015 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef __MONOLITHIUM_EXCEPTION_H__
#define __MONOLITHIUM_EXCEPTION_H__

#include "defs.h"
#include "cpu.h"
#include "object.h"

#ifdef __MONOLITIHUM_KERNEL_MODE__
#define EH_TRY if (get_current_thread() != NULL) { exception_handler_t ___handler; if (save_kernel_handler(&___handler) == 0)
#else
#define EH_TRY if (TRUE) { exception_handler_t ___handler; if (syscall(SYSCALL_SAVE_EXCEPTION_HANDLER, &___handler) == 0)
#endif

#define EH_CATCH else
#define EH_DONE syscall(SYSCALL_RESTORE_EXCEPTION_HANDLER, &___handler); }
#define EH_ESCAPE(x) do { syscall(SYSCALL_RESTORE_EXCEPTION_HANDLER, &___handler); x; } while (FALSE)

typedef registers_t exception_handler_t;

typedef enum
{
    EXCEPTION_BREAKPOINT,
    EXCEPTION_ARITHMETIC,
    EXCEPTION_ASSERTION,
    EXCEPTION_BAD_OPERATION,
    EXCEPTION_MEMORY_ACCESS,
    EXCEPTION_CUSTOM,
} exception_t;

typedef struct
{
    exception_t number;
    registers_t state;
    dword_t parameters[4];
} exception_info_t;

sysret_t syscall_get_exception_info(exception_info_t *info);
sysret_t syscall_raise_exception(handle_t thread, const exception_info_t *info);
sysret_t syscall_save_exception_handler(exception_handler_t *old_handler);
sysret_t syscall_restore_exception_handler(const exception_handler_t *old_handler);

#endif
