Files
wasmer/lib/clif-backend/src/signal/windows.rs

96 lines
3.4 KiB
Rust
Raw Normal View History

use crate::relocation::{TrapCode, TrapData};
2019-04-22 15:06:40 -07:00
use crate::signal::{HandlerData, RunErr};
use crate::trampoline::Trampoline;
use std::cell::Cell;
use std::ffi::c_void;
2019-04-09 16:46:01 -07:00
use std::ptr::{self, NonNull};
2019-03-15 14:10:17 -07:00
use wasmer_runtime_core::error::{RuntimeError, RuntimeResult};
2019-04-22 15:06:40 -07:00
use wasmer_runtime_core::typed_func::WasmTrapInfo;
use wasmer_runtime_core::vm::Ctx;
use wasmer_runtime_core::vm::Func;
use wasmer_win_exception_handler::CallProtectedData;
pub use wasmer_win_exception_handler::_call_protected;
use winapi::shared::minwindef::DWORD;
use winapi::um::minwinbase::{
EXCEPTION_ACCESS_VIOLATION, EXCEPTION_FLT_DENORMAL_OPERAND, EXCEPTION_FLT_DIVIDE_BY_ZERO,
EXCEPTION_FLT_INEXACT_RESULT, EXCEPTION_FLT_INVALID_OPERATION, EXCEPTION_FLT_OVERFLOW,
EXCEPTION_FLT_STACK_CHECK, EXCEPTION_FLT_UNDERFLOW, EXCEPTION_ILLEGAL_INSTRUCTION,
EXCEPTION_INT_DIVIDE_BY_ZERO, EXCEPTION_INT_OVERFLOW, EXCEPTION_STACK_OVERFLOW,
};
thread_local! {
pub static CURRENT_EXECUTABLE_BUFFER: Cell<*const c_void> = Cell::new(ptr::null());
}
pub fn call_protected(
handler_data: &HandlerData,
trampoline: Trampoline,
ctx: *mut Ctx,
2019-04-09 16:46:01 -07:00
func: NonNull<Func>,
param_vec: *const u64,
return_vec: *mut u64,
2019-04-22 15:06:40 -07:00
) -> Result<(), RunErr> {
// TODO: trap early
// user code error
// if let Some(msg) = super::TRAP_EARLY_DATA.with(|cell| cell.replace(None)) {
// return Err(RuntimeError::User { msg });
// }
let result = _call_protected(trampoline, ctx, func, param_vec, return_vec);
if let Ok(_) = result {
return Ok(());
}
let CallProtectedData {
code: signum,
2019-03-15 14:10:17 -07:00
exception_address,
instruction_pointer,
} = result.unwrap_err();
if let Some(TrapData {
trapcode,
srcloc: _,
}) = handler_data.lookup(instruction_pointer as _)
{
2019-04-22 15:06:40 -07:00
Err(RunErr::Trap(match signum as DWORD {
EXCEPTION_ACCESS_VIOLATION => WasmTrapInfo::MemoryOutOfBounds,
EXCEPTION_ILLEGAL_INSTRUCTION => match trapcode {
2019-04-22 15:06:40 -07:00
TrapCode::BadSignature => WasmTrapInfo::IncorrectCallIndirectSignature,
TrapCode::IndirectCallToNull => WasmTrapInfo::CallIndirectOOB,
TrapCode::HeapOutOfBounds => WasmTrapInfo::MemoryOutOfBounds,
TrapCode::TableOutOfBounds => WasmTrapInfo::CallIndirectOOB,
TrapCode::UnreachableCodeReached => WasmTrapInfo::Unreachable,
_ => WasmTrapInfo::Unknown,
},
2019-04-22 15:06:40 -07:00
EXCEPTION_STACK_OVERFLOW => WasmTrapInfo::Unknown,
EXCEPTION_INT_DIVIDE_BY_ZERO | EXCEPTION_INT_OVERFLOW => {
WasmTrapInfo::IllegalArithmetic
}
_ => WasmTrapInfo::Unknown,
}))
} else {
let signal = match signum as DWORD {
EXCEPTION_FLT_DENORMAL_OPERAND
| EXCEPTION_FLT_DIVIDE_BY_ZERO
| EXCEPTION_FLT_INEXACT_RESULT
| EXCEPTION_FLT_INVALID_OPERATION
| EXCEPTION_FLT_OVERFLOW
| EXCEPTION_FLT_STACK_CHECK
| EXCEPTION_FLT_UNDERFLOW => "floating-point exception",
EXCEPTION_ILLEGAL_INSTRUCTION => "illegal instruction",
EXCEPTION_ACCESS_VIOLATION => "segmentation violation",
_ => "unkown trapped signal",
};
2019-04-22 15:06:40 -07:00
let s = format!("unknown trap at {} - {}", exception_address, signal);
Err(RunErr::Error(Box::new(s)))
}
}
pub unsafe fn trigger_trap() -> ! {
// TODO
unimplemented!();
}