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

Improvements to windows-metadata #3268

Merged
merged 6 commits into from
Sep 11, 2024
Merged
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
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