Remove pod

This commit is contained in:
Yuke Peng 2023-04-01 22:34:27 -07:00 committed by Tate, Hongliang Tian
parent 4c7449d2c1
commit b3f4075bec
5 changed files with 0 additions and 264 deletions

View File

@ -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",

View File

@ -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"]}

View File

@ -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
}

View File

@ -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"]

View File

@ -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::*;