Skip to content

Commit

Permalink
Improvements to windows-metadata (#3268)
Browse files Browse the repository at this point in the history
  • Loading branch information
kennykerr authored Sep 11, 2024
1 parent 8e6ce39 commit 1b46399
Show file tree
Hide file tree
Showing 10 changed files with 320 additions and 322 deletions.
77 changes: 36 additions & 41 deletions crates/libs/bindgen/src/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,48 +266,43 @@ pub fn type_def_generics(def: TypeDef) -> Vec<Type> {
// TODO: namespace should not be required - it's a hack to accomodate Win32 metadata
// TODO: this is very Rust-specific and Win32-metadata specific with all of its translation. Replace with literal signature parser that just returns slice of types.
pub fn method_def_signature(namespace: &str, row: MethodDef, generics: &[Type]) -> Signature {
let reader = row.reader();
let mut blob = row.blob(4);
let call_flags = MethodCallAttributes(blob.read_usize() as u8);
let _param_count = blob.read_usize();
let mut return_type = reader.type_from_blob(&mut blob, None, generics);

let mut params: Vec<SignatureParam> = row
.params()
.filter_map(|param| {
let signature = row.signature(generics);

let mut return_type = signature.return_type.0;

if let Some(param) = signature.return_type.1 {
if param.has_attribute("ConstAttribute") {
return_type = return_type.clone().to_const_type();
}
}

let mut params: Vec<SignatureParam> = signature
.params
.into_iter()
.map(|(mut ty, param)| {
let param_is_const = param.has_attribute("ConstAttribute");
if param.sequence() == 0 {
if param_is_const {
return_type = return_type.clone().to_const_type();
}
None
} else {
let is_output = param.flags().contains(ParamAttributes::Out);
let mut ty = reader.type_from_blob(&mut blob, None, generics);

if let Some(name) = param_or_enum(param) {
let def = reader
.get_type_def(namespace, &name)
.next()
.expect("Enum not found");
ty = Type::PrimitiveOrEnum(
Box::new(ty),
Box::new(Type::TypeDef(def, Vec::new())),
);
}
let is_output = param.flags().contains(ParamAttributes::Out);

if param_is_const || !is_output {
ty = ty.to_const_type();
}
if !is_output {
ty = ty.to_const_ptr();
}
let kind = param_kind(param);
Some(SignatureParam {
def: param,
ty,
kind,
})
if let Some(name) = param_or_enum(param) {
let def = row
.reader()
.get_type_def(namespace, &name)
.next()
.expect("Enum not found");
ty = Type::PrimitiveOrEnum(Box::new(ty), Box::new(Type::TypeDef(def, Vec::new())));
}

if param_is_const || !is_output {
ty = ty.to_const_type();
}
if !is_output {
ty = ty.to_const_ptr();
}
let kind = param_kind(param);
SignatureParam {
def: param,
ty,
kind,
}
})
.collect();
Expand Down Expand Up @@ -395,7 +390,7 @@ pub fn method_def_signature(namespace: &str, row: MethodDef, generics: &[Type])
def: row,
params,
return_type,
call_flags,
call_flags: signature.call_flags,
}
}

Expand Down
6 changes: 3 additions & 3 deletions crates/libs/bindgen/src/rust/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,12 +157,12 @@ pub fn signature_cfg(writer: &Writer, method: metadata::MethodDef) -> Cfg {
cfg_add_attributes(&mut cfg, method);
cfg
}
fn signature_cfg_combine(writer: &Writer, signature: &metadata::MethodDefSig, cfg: &mut Cfg) {
type_cfg_combine(writer, &signature.return_type, cfg);
fn signature_cfg_combine(writer: &Writer, signature: &windows_metadata::Signature, cfg: &mut Cfg) {
type_cfg_combine(writer, &signature.return_type.0, cfg);
signature
.params
.iter()
.for_each(|param| type_cfg_combine(writer, param, cfg));
.for_each(|param| type_cfg_combine(writer, &param.0, cfg));
}

fn cfg_add_attributes<R: AsRow + Into<metadata::HasAttribute>>(cfg: &mut Cfg, row: R) {
Expand Down
56 changes: 30 additions & 26 deletions crates/libs/metadata/src/blob.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use super::*;

pub struct Blob {
pub file: &'static File,
pub slice: &'static [u8],
file: &'static File,
slice: &'static [u8],
}

impl std::ops::Deref for Blob {
Expand All @@ -14,11 +14,11 @@ impl std::ops::Deref for Blob {
}

impl Blob {
pub fn new(file: &'static File, slice: &'static [u8]) -> Self {
pub(crate) fn new(file: &'static File, slice: &'static [u8]) -> Self {
Self { file, slice }
}

pub fn peek_usize(&self) -> (usize, usize) {
fn peek(&self) -> (usize, usize) {
if self[0] & 0x80 == 0 {
(self[0] as usize, 1)
} else if self[0] & 0xC0 == 0x80 {
Expand All @@ -34,14 +34,12 @@ impl Blob {
}
}

pub fn read_usize(&mut self) -> usize {
let (value, offset) = self.peek_usize();
self.offset(offset);
value
pub fn decode<D: Decode>(&mut self) -> D {
D::decode(self.file, self.read_usize())
}

pub fn read_expected(&mut self, expected: usize) -> bool {
let (value, offset) = self.peek_usize();
pub(crate) fn try_read(&mut self, expected: usize) -> bool {
let (value, offset) = self.peek();
if value == expected {
self.offset(offset);
true
Expand All @@ -50,10 +48,10 @@ impl Blob {
}
}

pub fn read_modifiers(&mut self) -> Vec<TypeDefOrRef> {
pub(crate) fn read_modifiers(&mut self) -> Vec<TypeDefOrRef> {
let mut mods = vec![];
loop {
let (value, offset) = self.peek_usize();
let (value, offset) = self.peek();
if value != ELEMENT_TYPE_CMOD_OPT as usize && value != ELEMENT_TYPE_CMOD_REQD as usize {
break;
} else {
Expand All @@ -64,14 +62,20 @@ impl Blob {
mods
}

pub fn read_str(&mut self) -> &'static str {
pub fn read_usize(&mut self) -> usize {
let (value, offset) = self.peek();
self.offset(offset);
value
}

pub(crate) fn read_str(&mut self) -> &'static str {
let len = self.read_usize();
let value = unsafe { std::str::from_utf8_unchecked(&self.slice[..len]) };
self.offset(len);
value
}

pub fn read_string(self) -> String {
pub(crate) fn read_utf16(self) -> String {
let slice = self.slice;
if slice.as_ptr().align_offset(std::mem::align_of::<u16>()) > 0 {
let slice = slice
Expand All @@ -88,7 +92,7 @@ impl Blob {
}
}

pub fn read_bool(&mut self) -> bool {
pub(crate) fn read_bool(&mut self) -> bool {
// A bool is specified as "a single byte with value 0 (false) or 1 (true)".
match self.read_u8() {
0 => false,
Expand All @@ -97,67 +101,67 @@ impl Blob {
}
}

pub fn read_i8(&mut self) -> i8 {
pub(crate) fn read_i8(&mut self) -> i8 {
let value = i8::from_le_bytes(self[..1].try_into().unwrap());
self.offset(1);
value
}

pub fn read_u8(&mut self) -> u8 {
pub(crate) fn read_u8(&mut self) -> u8 {
let value = u8::from_le_bytes(self[..1].try_into().unwrap());
self.offset(1);
value
}

pub fn read_i16(&mut self) -> i16 {
pub(crate) fn read_i16(&mut self) -> i16 {
let value = i16::from_le_bytes(self[..2].try_into().unwrap());
self.offset(2);
value
}

pub fn read_u16(&mut self) -> u16 {
pub(crate) fn read_u16(&mut self) -> u16 {
let value = u16::from_le_bytes(self[..2].try_into().unwrap());
self.offset(2);
value
}

pub fn read_i32(&mut self) -> i32 {
pub(crate) fn read_i32(&mut self) -> i32 {
let value = i32::from_le_bytes(self[..4].try_into().unwrap());
self.offset(4);
value
}

pub fn read_u32(&mut self) -> u32 {
pub(crate) fn read_u32(&mut self) -> u32 {
let value = u32::from_le_bytes(self[..4].try_into().unwrap());
self.offset(4);
value
}

pub fn read_i64(&mut self) -> i64 {
pub(crate) fn read_i64(&mut self) -> i64 {
let value = i64::from_le_bytes(self[..8].try_into().unwrap());
self.offset(8);
value
}

pub fn read_u64(&mut self) -> u64 {
pub(crate) fn read_u64(&mut self) -> u64 {
let value = u64::from_le_bytes(self[..8].try_into().unwrap());
self.offset(8);
value
}

pub fn read_f32(&mut self) -> f32 {
pub(crate) fn read_f32(&mut self) -> f32 {
let value = f32::from_le_bytes(self[..4].try_into().unwrap());
self.offset(4);
value
}

pub fn read_f64(&mut self) -> f64 {
pub(crate) fn read_f64(&mut self) -> f64 {
let value = f64::from_le_bytes(self[..8].try_into().unwrap());
self.offset(8);
value
}

pub fn read_integer(&mut self, ty: Type) -> Value {
pub(crate) fn read_integer(&mut self, ty: Type) -> Value {
match ty {
Type::I8 => Value::I8(self.read_i8()),
Type::U8 => Value::U8(self.read_u8()),
Expand Down
11 changes: 0 additions & 11 deletions crates/libs/metadata/src/column.rs

This file was deleted.

Loading

0 comments on commit 1b46399

Please sign in to comment.