Add a trap code for misaligned atomic accesses. Called "unaligned" because that's what the thread proposal spectest uses. Use it in LLVM.

This commit is contained in:
Nick Lewycky
2020-05-19 12:31:59 -07:00
parent 88bc330761
commit 063863eb87
3 changed files with 12 additions and 7 deletions

View File

@ -1379,7 +1379,7 @@ fn trap_if_misaligned<'ctx>(
builder.position_at_end(not_aligned_block); builder.position_at_end(not_aligned_block);
builder.build_call( builder.build_call(
intrinsics.throw_trap, intrinsics.throw_trap,
&[intrinsics.trap_misaligned_atomic], &[intrinsics.trap_unaligned_atomic],
"throw", "throw",
); );
builder.build_unreachable(); builder.build_unreachable();

View File

@ -137,7 +137,7 @@ pub struct Intrinsics<'ctx> {
pub trap_illegal_arithmetic: BasicValueEnum<'ctx>, pub trap_illegal_arithmetic: BasicValueEnum<'ctx>,
pub trap_integer_division_by_zero: BasicValueEnum<'ctx>, pub trap_integer_division_by_zero: BasicValueEnum<'ctx>,
pub trap_bad_conversion_to_integer: BasicValueEnum<'ctx>, pub trap_bad_conversion_to_integer: BasicValueEnum<'ctx>,
pub trap_misaligned_atomic: BasicValueEnum<'ctx>, pub trap_unaligned_atomic: BasicValueEnum<'ctx>,
pub trap_table_access_oob: BasicValueEnum<'ctx>, pub trap_table_access_oob: BasicValueEnum<'ctx>,
// VM intrinsics. // VM intrinsics.
@ -420,7 +420,6 @@ impl<'ctx> Intrinsics<'ctx> {
trap_memory_oob: i32_ty trap_memory_oob: i32_ty
.const_int(TrapCode::OutOfBounds as _, false) .const_int(TrapCode::OutOfBounds as _, false)
.as_basic_value_enum(), .as_basic_value_enum(),
// TODO: split out div-by-zero and float-to-int
trap_illegal_arithmetic: i32_ty trap_illegal_arithmetic: i32_ty
.const_int(TrapCode::IntegerOverflow as _, false) .const_int(TrapCode::IntegerOverflow as _, false)
.as_basic_value_enum(), .as_basic_value_enum(),
@ -430,9 +429,8 @@ impl<'ctx> Intrinsics<'ctx> {
trap_bad_conversion_to_integer: i32_ty trap_bad_conversion_to_integer: i32_ty
.const_int(TrapCode::BadConversionToInteger as _, false) .const_int(TrapCode::BadConversionToInteger as _, false)
.as_basic_value_enum(), .as_basic_value_enum(),
// TODO: add misaligned atomic traps to wasmer runtime trap_unaligned_atomic: i32_ty
trap_misaligned_atomic: i32_ty .const_int(TrapCode::UnalignedAtomic as _, false)
.const_int(TrapCode::Interrupt as _, false)
.as_basic_value_enum(), .as_basic_value_enum(),
trap_table_access_oob: i32_ty trap_table_access_oob: i32_ty
.const_int(TrapCode::TableAccessOutOfBounds as _, false) .const_int(TrapCode::TableAccessOutOfBounds as _, false)

View File

@ -60,6 +60,9 @@ pub enum TrapCode {
/// Execution has potentially run too long and may be interrupted. /// Execution has potentially run too long and may be interrupted.
/// This trap is resumable. /// This trap is resumable.
Interrupt = 12, Interrupt = 12,
/// An atomic memory access was attempted with an unaligned pointer.
UnalignedAtomic = 13,
// /// A user-defined trap code. // /// A user-defined trap code.
// User(u16), // User(u16),
} }
@ -81,6 +84,7 @@ impl TrapCode {
Self::BadConversionToInteger => "invalid conversion to integer", Self::BadConversionToInteger => "invalid conversion to integer",
Self::UnreachableCodeReached => "unreachable", Self::UnreachableCodeReached => "unreachable",
Self::Interrupt => "interrupt", Self::Interrupt => "interrupt",
Self::UnalignedAtomic => "unsaligned atomic access",
// Self::User(_) => unreachable!(), // Self::User(_) => unreachable!(),
} }
} }
@ -103,6 +107,7 @@ impl Display for TrapCode {
BadConversionToInteger => "bad_toint", BadConversionToInteger => "bad_toint",
UnreachableCodeReached => "unreachable", UnreachableCodeReached => "unreachable",
Interrupt => "interrupt", Interrupt => "interrupt",
UnalignedAtomic => "unalign_atom",
// User(x) => return write!(f, "user{}", x), // User(x) => return write!(f, "user{}", x),
}; };
f.write_str(identifier) f.write_str(identifier)
@ -128,6 +133,7 @@ impl FromStr for TrapCode {
"bad_toint" => Ok(BadConversionToInteger), "bad_toint" => Ok(BadConversionToInteger),
"unreachable" => Ok(UnreachableCodeReached), "unreachable" => Ok(UnreachableCodeReached),
"interrupt" => Ok(Interrupt), "interrupt" => Ok(Interrupt),
"unalign_atom" => Ok(UnalignedAtomic),
// _ if s.starts_with("user") => s[4..].parse().map(User).map_err(|_| ()), // _ if s.starts_with("user") => s[4..].parse().map(User).map_err(|_| ()),
_ => Err(()), _ => Err(()),
} }
@ -139,7 +145,7 @@ mod tests {
use super::*; use super::*;
// Everything but user-defined codes. // Everything but user-defined codes.
const CODES: [TrapCode; 13] = [ const CODES: [TrapCode; 14] = [
TrapCode::StackOverflow, TrapCode::StackOverflow,
TrapCode::HeapSetterOutOfBounds, TrapCode::HeapSetterOutOfBounds,
TrapCode::HeapAccessOutOfBounds, TrapCode::HeapAccessOutOfBounds,
@ -153,6 +159,7 @@ mod tests {
TrapCode::BadConversionToInteger, TrapCode::BadConversionToInteger,
TrapCode::UnreachableCodeReached, TrapCode::UnreachableCodeReached,
TrapCode::Interrupt, TrapCode::Interrupt,
TrapCode::UnalignedAtomic,
]; ];
#[test] #[test]