mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-08 21:06:48 +00:00
Remove pod
This commit is contained in:
parent
4c7449d2c1
commit
b3f4075bec
@ -19,8 +19,6 @@ jinux-framebuffer = { path = "services/comps/framebuffer" }
|
||||
members = [
|
||||
"boot",
|
||||
"framework/jinux-frame",
|
||||
"framework/pod",
|
||||
"framework/pod-derive",
|
||||
"services/comps/pci",
|
||||
"services/comps/virtio",
|
||||
"services/comps/input",
|
||||
|
@ -1,14 +0,0 @@
|
||||
[package]
|
||||
name = "pod-derive"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
proc-macro2 = "1.0"
|
||||
quote = "1.0"
|
||||
syn = {version = "1.0.90", features = ["extra-traits"]}
|
@ -1,166 +0,0 @@
|
||||
//! This crate is used to provide a procedural macro to derive Pod trait defined in framework/pod.
|
||||
//! When use this crate, framework/pod should also be added as a dependency.
|
||||
//! This macro should only be used outside
|
||||
//! When derive Pod trait, we will do a check whether the derive is safe since Pod trait is an unsafe trait.
|
||||
//! For struct, we will check that the struct has valid repr (e.g,. repr(C), repr(u8)), and each field is Pod type.
|
||||
//! For union and enum, we only check the valid repr.
|
||||
|
||||
use proc_macro2::{Ident, TokenStream};
|
||||
use quote::quote;
|
||||
use syn::{
|
||||
parse_macro_input, Attribute, Data, DataEnum, DataStruct, DataUnion, DeriveInput, Fields,
|
||||
Generics,
|
||||
};
|
||||
|
||||
#[proc_macro_derive(Pod)]
|
||||
pub fn derive_pod(input_token: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
let input = parse_macro_input!(input_token as DeriveInput);
|
||||
expand_derive_pod(input).into()
|
||||
}
|
||||
|
||||
const ALLOWED_REPRS: [&'static str; 11] = [
|
||||
"C", "u8", "i8", "u16", "i16", "u32", "i32", "u64", "i64", "usize", "isize",
|
||||
];
|
||||
|
||||
fn expand_derive_pod(input: DeriveInput) -> TokenStream {
|
||||
let attrs = input.attrs;
|
||||
let ident = input.ident;
|
||||
let generics = input.generics;
|
||||
match input.data {
|
||||
Data::Struct(data_struct) => impl_pod_for_struct(data_struct, generics, ident, attrs),
|
||||
Data::Union(data_union) => impl_pod_for_union(data_union, generics, ident, attrs),
|
||||
Data::Enum(data_enum) => impl_pod_for_enum(data_enum, attrs, generics, ident),
|
||||
}
|
||||
}
|
||||
|
||||
fn impl_pod_for_struct(
|
||||
data_struct: DataStruct,
|
||||
generics: Generics,
|
||||
ident: Ident,
|
||||
attrs: Vec<Attribute>,
|
||||
) -> TokenStream {
|
||||
if !has_valid_repr(attrs) {
|
||||
panic!("{} has invalid repr to implement Pod", ident.to_string());
|
||||
}
|
||||
let DataStruct { fields, .. } = data_struct;
|
||||
let fields = match fields {
|
||||
Fields::Named(fields_named) => fields_named.named,
|
||||
Fields::Unnamed(fields_unnamed) => fields_unnamed.unnamed,
|
||||
Fields::Unit => panic!("derive pod does not work for struct with unit field"),
|
||||
};
|
||||
|
||||
// deal with generics
|
||||
let (impl_generics, type_generics, where_clause) = generics.split_for_impl();
|
||||
|
||||
let pod_where_predicates = fields
|
||||
.into_iter()
|
||||
.map(|field| {
|
||||
let field_ty = field.ty;
|
||||
quote! {
|
||||
#field_ty: ::pod::Pod
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// if where_clause is none, we should add a `where` word manually.
|
||||
if where_clause.is_none() {
|
||||
quote! {
|
||||
#[automatically_derived]
|
||||
unsafe impl #impl_generics ::pod::Pod #type_generics for #ident where #(#pod_where_predicates),* {}
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
#[automatically_derived]
|
||||
unsafe impl #impl_generics ::pod::Pod #type_generics for #ident #where_clause, #(#pod_where_predicates),* {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn impl_pod_for_union(
|
||||
data_union: DataUnion,
|
||||
generics: Generics,
|
||||
ident: Ident,
|
||||
attrs: Vec<Attribute>,
|
||||
) -> TokenStream {
|
||||
if !has_valid_repr(attrs) {
|
||||
panic!("{} has invalid repr to implement Pod", ident.to_string());
|
||||
}
|
||||
let fields = data_union.fields.named;
|
||||
// deal with generics
|
||||
let (impl_generics, type_generics, where_clause) = generics.split_for_impl();
|
||||
|
||||
let pod_where_predicates = fields
|
||||
.into_iter()
|
||||
.map(|field| {
|
||||
let field_ty = field.ty;
|
||||
quote! {
|
||||
#field_ty: ::pod::Pod
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// if where_clause is none, we should add a `where` word manually.
|
||||
if where_clause.is_none() {
|
||||
quote! {
|
||||
#[automatically_derived]
|
||||
unsafe impl #impl_generics ::pod::Pod #type_generics for #ident where #(#pod_where_predicates),* {}
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
#[automatically_derived]
|
||||
unsafe impl #impl_generics ::pod::Pod #type_generics for #ident #where_clause, #(#pod_where_predicates),* {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn impl_pod_for_enum(
|
||||
data_enum: DataEnum,
|
||||
attrs: Vec<Attribute>,
|
||||
generics: Generics,
|
||||
ident: Ident,
|
||||
) -> TokenStream {
|
||||
if !has_valid_repr(attrs) {
|
||||
panic!(
|
||||
"{} does not have invalid repr to implement Pod.",
|
||||
ident.to_string()
|
||||
);
|
||||
}
|
||||
|
||||
// check variant
|
||||
for variant in data_enum.variants {
|
||||
if None == variant.discriminant {
|
||||
panic!("Enum can only have fields like Variant=1");
|
||||
}
|
||||
}
|
||||
|
||||
// deal with generics
|
||||
let (impl_generics, type_generics, where_clause) = generics.split_for_impl();
|
||||
quote! {
|
||||
#[automatically_derived]
|
||||
unsafe impl #impl_generics ::pod::Pod #type_generics for #ident #where_clause {}
|
||||
}
|
||||
}
|
||||
|
||||
fn has_valid_repr(attrs: Vec<Attribute>) -> bool {
|
||||
for attr in attrs {
|
||||
if let Some(ident) = attr.path.get_ident() {
|
||||
if "repr" == ident.to_string().as_str() {
|
||||
let repr = attr.tokens.to_string();
|
||||
let repr = repr.replace("(", "").replace(")", "");
|
||||
let reprs = repr
|
||||
.split(",")
|
||||
.map(|one_repr| one_repr.trim())
|
||||
.collect::<Vec<_>>();
|
||||
if let Some(_) = ALLOWED_REPRS.iter().position(|allowed_repr| {
|
||||
reprs
|
||||
.iter()
|
||||
.position(|one_repr| one_repr == allowed_repr)
|
||||
.is_some()
|
||||
}) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
[package]
|
||||
name = "pod"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
pod-derive = {path = "../pod-derive", optional = true}
|
||||
|
||||
[features]
|
||||
default = ["derive"]
|
||||
derive = ["pod-derive"]
|
@ -1,69 +0,0 @@
|
||||
#![no_std]
|
||||
|
||||
use core::mem::MaybeUninit;
|
||||
|
||||
/// A marker trait for plain old data (POD).
|
||||
///
|
||||
/// A POD type `T:Pod` supports converting to and from arbitrary
|
||||
/// `mem::size_of::<T>()` bytes _safely_.
|
||||
/// For example, simple primitive types like `u8` and `i16`
|
||||
/// are POD types. But perhaps surprisingly, `bool` is not POD
|
||||
/// because Rust compiler makes implicit assumption that
|
||||
/// a byte of `bool` has a value of either `0` or `1`.
|
||||
/// Interpreting a byte of value `3` has a `bool` value has
|
||||
/// undefined behavior.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Marking a non-POD type as POD may cause undefined behaviors.
|
||||
pub unsafe trait Pod: Copy + Sized {
|
||||
/// Creates a new instance of Pod type that is filled with zeroes.
|
||||
fn new_zeroed() -> Self {
|
||||
// SAFETY. An all-zero value of `T: Pod` is always valid.
|
||||
unsafe { core::mem::zeroed() }
|
||||
}
|
||||
|
||||
/// Creates a new instance of Pod type with uninitialized content.
|
||||
fn new_uninit() -> Self {
|
||||
// SAFETY. A value of `T: Pod` can have arbitrary bits.
|
||||
#[allow(clippy::uninit_assumed_init)]
|
||||
unsafe {
|
||||
MaybeUninit::uninit().assume_init()
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new instance from the given bytes.
|
||||
fn from_bytes(bytes: &[u8]) -> Self {
|
||||
let mut new_self = Self::new_uninit();
|
||||
let copy_len = new_self.as_bytes().len();
|
||||
new_self.as_bytes_mut().copy_from_slice(&bytes[..copy_len]);
|
||||
new_self
|
||||
}
|
||||
|
||||
/// As a slice of bytes.
|
||||
fn as_bytes(&self) -> &[u8] {
|
||||
let ptr = self as *const Self as *const u8;
|
||||
let len = core::mem::size_of::<Self>();
|
||||
unsafe { core::slice::from_raw_parts(ptr, len) }
|
||||
}
|
||||
|
||||
/// As a mutable slice of bytes.
|
||||
fn as_bytes_mut(&mut self) -> &mut [u8] {
|
||||
let ptr = self as *mut Self as *mut u8;
|
||||
let len = core::mem::size_of::<Self>();
|
||||
unsafe { core::slice::from_raw_parts_mut(ptr, len) }
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_pod_for {
|
||||
($($pod_ty:ty),*) => {
|
||||
$(unsafe impl Pod for $pod_ty {})*
|
||||
};
|
||||
}
|
||||
// impl Pod for primitive types
|
||||
impl_pod_for!(u8, u16, u32, u64, i8, i16, i32, i64, isize, usize);
|
||||
// impl Pod for array
|
||||
unsafe impl<T: Pod, const N: usize> Pod for [T; N] {}
|
||||
|
||||
#[cfg(feature = "derive")]
|
||||
pub use pod_derive::*;
|
Loading…
x
Reference in New Issue
Block a user