Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

extract raw traits for internal usage, #3 #5

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 8 additions & 24 deletions src/action.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use xed_sys::*;

use super::Flag;
use super::{
raw::{AsRaw, IntoRaw},
Flag,
};

crate::macros::xed_enum! {
pub enum Action => XED_FLAG_ACTION {
Expand Down Expand Up @@ -39,31 +42,12 @@ impl Action {
}
}

#[repr(transparent)]
pub struct FlagAction(xed_flag_action_t);
crate::macros::wrapper_type! {
#[derive(FromRaw, AsRaw, AsRawMut, IntoRaw)]
pub struct FlagAction(xed_flag_action_t);
}

impl FlagAction {
pub fn from_ref(raw: &xed_flag_action_t) -> &Self {
// SAFETY: SimpleFlag is #[repr(transparent)]
unsafe { std::mem::transmute(raw) }
}

pub fn from_raw(raw: xed_flag_action_t) -> Self {
Self(raw)
}

pub fn into_raw(self) -> xed_flag_action_t {
self.0
}

pub fn as_raw(&self) -> &xed_flag_action_t {
&self.0
}

pub fn as_raw_mut(&mut self) -> &mut xed_flag_action_t {
&mut self.0
}

/// The action performed by this flag.
pub fn action(&self) -> Action {
// Note: xed takes an index i but it is entirely unused by the actual function
Expand Down
34 changes: 8 additions & 26 deletions src/chip_features.rs
Original file line number Diff line number Diff line change
@@ -1,31 +1,13 @@
use xed_sys::*;

use super::{Chip, IsaSet};

#[repr(transparent)]
pub struct ChipFeatures(xed_chip_features_t);

impl ChipFeatures {
pub fn from_ref(raw: &xed_chip_features_t) -> &Self {
// SAFETY: ChipFeatures is #[repr(transparent)]
unsafe { std::mem::transmute(raw) }
}

pub fn from_raw(raw: xed_chip_features_t) -> Self {
Self(raw)
}

pub fn into_raw(self) -> xed_chip_features_t {
self.0
}

pub fn as_raw(&self) -> &xed_chip_features_t {
&self.0
}

pub fn as_raw_mut(&mut self) -> &mut xed_chip_features_t {
&mut self.0
}
use super::{
raw::{AsRawMut, IntoRaw},
Chip, IsaSet,
};

crate::macros::wrapper_type! {
#[derive(FromRaw, AsRaw, AsRawMut, IntoRaw)]
pub struct ChipFeatures(xed_chip_features_t);
}

impl ChipFeatures {
Expand Down
2 changes: 1 addition & 1 deletion src/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::mem::MaybeUninit;

use xed_sys::*;

use super::{ChipFeatures, DecodedInst, Error, State};
use super::{raw::AsRawMut, ChipFeatures, DecodedInst, Error, State};

/// Options for [`decode`].
///
Expand Down
3 changes: 2 additions & 1 deletion src/decoded_inst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::marker::PhantomData;
use xed_sys::*;

use crate::{
raw::{FromRaw, IntoRaw},
Attribute, Category, Chip, Extension, IClass, IForm, IsaSet, Operand, OperandAction,
OperandElementType, Register, SimpleFlag, Syntax,
};
Expand Down Expand Up @@ -475,7 +476,7 @@ impl<'d> DecodedInst<'d> {
unsafe {
xed_decoded_inst_get_rflags_info(self.as_raw())
.as_ref()
.map(SimpleFlag::from_ref)
.map(FromRaw::from_ref)
}
}

Expand Down
28 changes: 6 additions & 22 deletions src/flag_set.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,13 @@
use xed_sys::*;

pub struct FlagSet(xed_flag_set_t);
use crate::raw::AsRaw;

impl FlagSet {
pub fn from_ref(raw: &xed_flag_set_t) -> &Self {
// SAFETY: SimpleFlag is #[repr(transparent)]
unsafe { std::mem::transmute(raw) }
}

pub fn from_raw(raw: xed_flag_set_t) -> Self {
Self(raw)
}

pub fn into_raw(self) -> xed_flag_set_t {
self.0
}

pub fn as_raw(&self) -> &xed_flag_set_t {
&self.0
}

pub fn as_raw_mut(&mut self) -> &mut xed_flag_set_t {
&mut self.0
}
crate::macros::wrapper_type! {
#[derive(FromRaw, AsRaw, AsRawMut, IntoRaw)]
pub struct FlagSet(xed_flag_set_t);
}

impl FlagSet {
/// Get the flags as a mask.
pub fn as_mask(&self) -> u32 {
unsafe { xed_flag_set_mask(self.as_raw()) }
Expand Down
57 changes: 8 additions & 49 deletions src/inst.rs
Original file line number Diff line number Diff line change
@@ -1,38 +1,18 @@
use xed_sys::*;

use super::{
raw::{AsRaw, IntoRaw},
Attribute, Category, DecodedInst, Exception, Extension, IClass, IForm, IsaSet, NonTerminal,
Operand, OperandAction, OperandElementXType, OperandType, OperandValue, OperandVisibility,
OperandWidth, Register,
};

used_in_docs!(DecodedInst, OperandValue);

/// Constant information about a decoded instruction form.
#[repr(transparent)]
pub struct Inst(xed_inst_t);

impl Inst {
pub fn from_ref(raw: &xed_inst_t) -> &Self {
// SAFETY: Inst is #[repr(transparent)]
unsafe { std::mem::transmute(raw) }
}

pub fn from_raw(raw: xed_inst_t) -> Self {
Self(raw)
}

pub fn into_raw(self) -> xed_inst_t {
self.0
}

pub fn as_raw(&self) -> &xed_inst_t {
&self.0
}

pub fn as_raw_mut(&mut self) -> &mut xed_inst_t {
&mut self.0
}
crate::macros::wrapper_type! {
/// Constant information about a decoded instruction form.
#[derive(FromRaw, AsRaw, AsRawMut, IntoRaw)]
pub struct Inst(xed_inst_t);
}

impl Inst {
Expand Down Expand Up @@ -99,30 +79,9 @@ impl Inst {
}
}

#[repr(transparent)]
pub struct InstOperand(xed_operand_t);

impl InstOperand {
pub fn from_ref(raw: &xed_operand_t) -> &Self {
// SAFETY: Inst is #[repr(transparent)]
unsafe { std::mem::transmute(raw) }
}

pub fn from_raw(raw: xed_operand_t) -> Self {
Self(raw)
}

pub fn into_raw(self) -> xed_operand_t {
self.0
}

pub fn as_raw(&self) -> &xed_operand_t {
&self.0
}

pub fn as_raw_mut(&mut self) -> &mut xed_operand_t {
&mut self.0
}
crate::macros::wrapper_type! {
#[derive(FromRaw, AsRaw, AsRawMut, IntoRaw)]
pub struct InstOperand(xed_operand_t);
}

impl InstOperand {
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ mod operand_type;
mod operand_visibility;
mod operand_width;
mod operand_xtype;
mod raw;
mod register;
mod simple_flag;
mod state;
Expand Down
2 changes: 2 additions & 0 deletions src/macros/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
//! This module contains various macros used in the rest of the codebase.

mod wrapper_enum;
mod wrapper_type;
mod xed_enum;

pub(crate) use wrapper_enum::{is_contiguous, wrapper_enum};
pub(crate) use wrapper_type::wrapper_type;
pub(crate) use xed_enum::xed_enum;

macro_rules! first {
Expand Down
75 changes: 75 additions & 0 deletions src/macros/wrapper_type.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// FIXME: move to a procedural macros
macro_rules! wrapper_type {
(
$( #[doc = $comment:literal] )?
#[derive ( $( $trait:ident ),* ) ]
$vis:vis struct $name:ident ( $ctype:ident );
) => {
$( #[doc = $comment] )?
#[repr(transparent)]
$vis struct $name( $ctype );

crate::macros::wrapper_type! (__impl $name $ctype $( $trait )* );
};

(
__impl $name:ident $ctype:ident FromRaw $( $rest:ident )*
) => {
impl crate::raw::FromRaw for $name {
type CType = $ctype;

fn from_raw(raw: Self::CType) -> Self {
$name ( raw )
}

fn from_ref(raw: &Self::CType) -> &Self {
unsafe { std::mem::transmute(raw) }
}
}

crate::macros::wrapper_type! (__impl $name $ctype $( $rest )* );
};

(
__impl $name:ident $ctype:ident AsRaw $( $rest:ident )*
) => {
impl crate::raw::AsRaw for $name {
fn as_raw(&self) -> &Self::CType {
&self.0
}
}

crate::macros::wrapper_type! (__impl $name $ctype $( $rest )* );
};

(
__impl $name:ident $ctype:ident AsRawMut $( $rest:ident )*
) => {
impl crate::raw::AsRawMut for $name {
fn as_raw_mut(&mut self) -> &mut Self::CType {
&mut self.0
}
}

crate::macros::wrapper_type! (__impl $name $ctype $( $rest )* );
};

(
__impl $name:ident $ctype:ident IntoRaw $( $rest:ident )*
) => {
impl crate::raw::IntoRaw for $name {
fn into_raw(self) -> Self::CType {
self.0
}
}

crate::macros::wrapper_type! (__impl $name $ctype $( $rest )* );
};

(
__impl $name:ident $ctype:ident
) => {
};
}

pub(crate) use wrapper_type;
28 changes: 20 additions & 8 deletions src/macros/xed_enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ macro_rules! xed_enum {
$( invalid = $invalid:ident; )?
} => {
$( #[$attr] )*
#[repr(transparent)]
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
$vis struct $name(std::num::NonZeroU32);

Expand All @@ -35,13 +36,11 @@ macro_rules! xed_enum {
);
)*
}
}

impl $name {
#[doc = concat!(
"Create a `", stringify!($name), "` from the underlying enum value."
)]
pub const fn from_raw(value: u32) -> Option<Self> {
pub(crate) const fn from_raw(value: u32) -> Option<Self> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That this is const is actually rather important. It means that users of xed can create their own constants for new variants introduced by xed-sys before we get around to adding them here.

paste::paste! {
if value >= [< $base _ LAST >] {
return None;
Expand All @@ -53,16 +52,29 @@ macro_rules! xed_enum {
None => None
}
}
}

impl crate::raw::FromRaw for $name {
type CType = u32;

fn from_raw(value: Self::CType) -> Self {
$name::from_raw(value).expect("underlying enum value was invalid")
}

fn from_ref(raw: &Self::CType) -> &Self {
unsafe { std::mem::transmute(raw) }
}
}

/// Convert this value into the underlying enum value.
pub const fn into_raw(self) -> u32 {
impl crate::raw::IntoRaw for $name {
fn into_raw(self) -> u32 {
self.0.get()
}
}

impl From<$name> for u32 {
fn from(value: $name) -> u32 {
value.into_raw()
crate::raw::IntoRaw::into_raw(value)
}
}

Expand All @@ -82,7 +94,7 @@ macro_rules! xed_enum {

impl std::fmt::Debug for $name {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let value = self.into_raw();
let value = crate::raw::IntoRaw::into_raw(*self);
let cstr = unsafe {
paste::paste!($crate::macros::first!(
$( [ xed_sys::[< $enum_name 2str >](value) ] )?
Expand All @@ -109,7 +121,7 @@ macro_rules! xed_enum {
let max = variants
.iter()
.copied()
.map(|variant| variant.into_raw())
.map(crate::raw::IntoRaw::into_raw)
.max();

match max {
Expand Down
Loading