115 lines
3.0 KiB
Rust
115 lines
3.0 KiB
Rust
use std::str::FromStr;
|
|
|
|
use proc_macro2::TokenStream;
|
|
use quote::quote;
|
|
use syn::Ident;
|
|
|
|
use crate::TargetEnv;
|
|
|
|
use super::{Type, TypeKind, TypeWidth};
|
|
|
|
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
|
pub enum AbiPrimitive {
|
|
Unit,
|
|
Bool,
|
|
U8,
|
|
I8,
|
|
U16,
|
|
I16,
|
|
U31,
|
|
U32,
|
|
I32,
|
|
U64,
|
|
I64,
|
|
U128,
|
|
USize,
|
|
}
|
|
|
|
impl Type for AbiPrimitive {
|
|
fn width(&self, env: &TargetEnv) -> TypeWidth {
|
|
match self {
|
|
Self::Unit => TypeWidth::Zero,
|
|
Self::U8 | Self::I8 => TypeWidth::U8,
|
|
Self::U16 | Self::I16 => TypeWidth::U16,
|
|
Self::U31 => TypeWidth::U31,
|
|
Self::U32 | Self::I32 => TypeWidth::U32,
|
|
Self::U64 | Self::I64 => TypeWidth::U64,
|
|
Self::U128 => TypeWidth::U128,
|
|
Self::USize => env.thin_pointer_width,
|
|
// ???
|
|
Self::Bool => TypeWidth::U32,
|
|
}
|
|
}
|
|
|
|
fn kind(&self) -> TypeKind {
|
|
TypeKind::Other
|
|
}
|
|
|
|
fn as_rust_type(&self) -> TokenStream {
|
|
match self {
|
|
Self::Unit => quote!(()),
|
|
Self::U8 => quote!(u8),
|
|
Self::I8 => quote!(i8),
|
|
Self::U16 => quote!(u16),
|
|
Self::I16 => quote!(i16),
|
|
Self::U32 => quote!(u32),
|
|
Self::I32 => quote!(i32),
|
|
Self::U64 => quote!(u64),
|
|
Self::I64 => quote!(i64),
|
|
Self::U128 => quote!(u128),
|
|
Self::USize => quote!(usize),
|
|
Self::Bool => quote!(bool),
|
|
|
|
Self::U31 => todo!(),
|
|
}
|
|
}
|
|
|
|
fn emit_to_syscall_arguments(&self, env: &TargetEnv, value: &Ident) -> TokenStream {
|
|
match self {
|
|
Self::USize => quote!(#value),
|
|
Self::U128 => todo!("Emit to syscall for u128"),
|
|
Self::U64 if env.thin_pointer_width == TypeWidth::U32 => todo!(),
|
|
_ => quote!(#value as usize),
|
|
}
|
|
}
|
|
|
|
fn emit_from_syscall_arguments(
|
|
&self,
|
|
env: &TargetEnv,
|
|
args: &Ident,
|
|
index: usize,
|
|
) -> (TokenStream, usize) {
|
|
match self {
|
|
Self::Bool => (quote!(#args[#index] != 0), 1),
|
|
Self::U128 => todo!("Emit from syscall for u128"),
|
|
Self::U64 if env.thin_pointer_width == TypeWidth::U32 => todo!(),
|
|
_ => {
|
|
let ty = self.as_rust_type();
|
|
(quote!(#args[#index] as #ty), 1)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
impl FromStr for AbiPrimitive {
|
|
type Err = ();
|
|
|
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
match s {
|
|
"i8" => Ok(Self::I8),
|
|
"u8" => Ok(Self::U8),
|
|
"i16" => Ok(Self::I16),
|
|
"u16" => Ok(Self::U16),
|
|
"i32" => Ok(Self::I32),
|
|
"u31" => Ok(Self::U31),
|
|
"u32" => Ok(Self::U32),
|
|
"i64" => Ok(Self::I64),
|
|
"u64" => Ok(Self::U64),
|
|
"u128" => Ok(Self::U128),
|
|
"bool" => Ok(Self::Bool),
|
|
"usize" => Ok(Self::USize),
|
|
_ => Err(()),
|
|
}
|
|
}
|
|
}
|