Skip to content

Commit

Permalink
Basics of metadata generation (#1633)
Browse files Browse the repository at this point in the history
  • Loading branch information
kennykerr authored Mar 25, 2022
1 parent c31774a commit b3ebe39
Show file tree
Hide file tree
Showing 75 changed files with 856 additions and 59 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,10 @@ jobs:
cargo clippy -p test_weak_ref &&
cargo clippy -p test_win32 &&
cargo clippy -p test_win32_arrays &&
cargo clippy -p test_writer &&
cargo clippy -p tool_bindings &&
cargo clippy -p tool_gnu &&
cargo clippy -p tool_ilrs &&
cargo clippy -p tool_msvc &&
cargo clippy -p tool_sys &&
cargo clippy -p tool_windows &&
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,10 @@ jobs:
cargo test --target ${{ matrix.target }} -p test_weak_ref &&
cargo test --target ${{ matrix.target }} -p test_win32 &&
cargo test --target ${{ matrix.target }} -p test_win32_arrays &&
cargo test --target ${{ matrix.target }} -p test_writer &&
cargo test --target ${{ matrix.target }} -p tool_bindings &&
cargo test --target ${{ matrix.target }} -p tool_gnu &&
cargo test --target ${{ matrix.target }} -p tool_ilrs &&
cargo test --target ${{ matrix.target }} -p tool_msvc &&
cargo test --target ${{ matrix.target }} -p tool_sys &&
cargo test --target ${{ matrix.target }} -p tool_windows &&
Expand Down
2 changes: 1 addition & 1 deletion crates/libs/bindgen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use functions::*;
pub use gen::*;
use helpers::*;
use iterator::*;
use metadata::*;
use metadata::reader::*;
use method_names::*;
use methods::*;
use names::*;
Expand Down
45 changes: 2 additions & 43 deletions crates/libs/metadata/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,43 +1,2 @@
mod array_info;
mod async_kind;
mod blob;
mod cfg;
mod codes;
mod constant_value;
mod file;
mod guid;
mod interface_kind;
mod param_flags;
mod row;
mod signature;
mod signature_kind;
mod tables;
mod traits;
mod r#type;
mod type_kind;
mod type_name;
mod type_reader;
mod type_tree;
mod workspace;

pub use array_info::*;
pub use async_kind::*;
pub use blob::*;
pub use cfg::*;
pub use codes::*;
pub use constant_value::*;
pub use file::*;
pub use guid::*;
pub use interface_kind::*;
pub use param_flags::*;
pub use r#type::*;
pub use row::*;
pub use signature::*;
pub use signature_kind::*;
pub use tables::*;
pub use traits::*;
pub use type_kind::*;
pub use type_name::*;
pub use type_reader::*;
pub use type_tree::*;
pub use workspace::*;
pub mod reader;
pub mod writer;
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -474,14 +474,14 @@ impl File {
file
}

pub(crate) fn new<P: AsRef<std::path::Path>>(filename: P) -> Self {
pub fn new<P: AsRef<std::path::Path>>(filename: P) -> Self {
let filename = filename.as_ref();
let bytes = std::fs::read(filename).unwrap_or_else(|e| panic!("Could not read file {:?}: {:?}", filename, e));

Self::from_bytes(filename.file_name().expect("Invalid .winmd path").to_string_lossy().to_string(), bytes)
}

pub(crate) fn type_def_table(&self) -> &TableData {
pub fn type_def_table(&self) -> &TableData {
&self.tables[TableIndex::TypeDef as usize]
}

Expand Down
File renamed without changes.
File renamed without changes.
43 changes: 43 additions & 0 deletions crates/libs/metadata/src/reader/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
mod array_info;
mod async_kind;
mod blob;
mod cfg;
mod codes;
mod constant_value;
mod file;
mod guid;
mod interface_kind;
mod param_flags;
mod row;
mod signature;
mod signature_kind;
mod tables;
mod traits;
mod r#type;
mod type_kind;
mod type_name;
mod type_reader;
mod type_tree;
mod workspace;

pub use array_info::*;
pub use async_kind::*;
pub use blob::*;
pub use cfg::*;
pub use codes::*;
pub use constant_value::*;
pub use file::*;
pub use guid::*;
pub use interface_kind::*;
pub use param_flags::*;
pub use r#type::*;
pub use row::*;
pub use signature::*;
pub use signature_kind::*;
pub use tables::*;
pub use traits::*;
pub use type_kind::*;
pub use type_name::*;
pub use type_reader::*;
pub use type_tree::*;
pub use workspace::*;
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,9 @@ fn get_workspace_winmds() -> Vec<File> {
push_dir(&mut result, &dir);

if !result.iter().any(|file| file.name.starts_with("Windows.")) {
result.push(File::from_bytes("Windows.winmd".to_string(), include_bytes!("../default/Windows.winmd").to_vec()));
result.push(File::from_bytes("Windows.Win32.winmd".to_string(), include_bytes!("../default/Windows.Win32.winmd").to_vec()));
result.push(File::from_bytes("Windows.Win32.Interop.winmd".to_string(), include_bytes!("../default/Windows.Win32.Interop.winmd").to_vec()));
result.push(File::from_bytes("Windows.winmd".to_string(), include_bytes!("../../default/Windows.winmd").to_vec()));
result.push(File::from_bytes("Windows.Win32.winmd".to_string(), include_bytes!("../../default/Windows.Win32.winmd").to_vec()));
result.push(File::from_bytes("Windows.Win32.Interop.winmd".to_string(), include_bytes!("../../default/Windows.Win32.Interop.winmd").to_vec()));
}

result
Expand Down
37 changes: 37 additions & 0 deletions crates/libs/metadata/src/writer/blobs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use super::*;

pub(crate) struct Blobs {
set: BTreeMap<Vec<u8>, usize>,
stream: Vec<u8>,
}

impl Blobs {
pub fn new() -> Self {
Self { set: BTreeMap::new(), stream: vec![0] }
}

pub fn insert(&mut self, value: &[u8]) -> u32 {
if value.is_empty() {
return 0;
}

let pos = self.stream.len();
let mut insert = false;

let pos = *self.set.entry(value.to_vec()).or_insert_with(|| {
insert = true;
pos
});

if insert {
self.stream.extend_from_slice(value);
}

pos as _
}

pub fn into_stream(mut self) -> Vec<u8> {
self.stream.resize(round(self.stream.len(), 4), 0);
self.stream
}
}
24 changes: 24 additions & 0 deletions crates/libs/metadata/src/writer/gen.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#[derive(Default)]
pub struct Gen {
// Source files to include.
pub sources: Vec<String>,

// Winmd files to include.
pub inputs: Vec<String>,

// Winmd files to reference.
pub references: Vec<String>,

// Name of resulting winmd file.
pub output: String,
}

impl Gen {
pub fn new() -> Self {
Self::default()
}
}

pub fn gen(_gen: &Gen) -> std::io::Result<()> {
Ok(())
}
19 changes: 19 additions & 0 deletions crates/libs/metadata/src/writer/helpers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use std::mem::*;
use std::slice::*;

pub fn round(size: usize, round: usize) -> usize {
let round = round - 1;
(size + round) & !round
}

pub trait Write {
fn write<T: Sized>(&mut self, value: &T);
}

impl Write for Vec<u8> {
fn write<T: Sized>(&mut self, value: &T) {
unsafe {
self.extend_from_slice(from_raw_parts(value as *const _ as _, size_of::<T>()));
}
}
}
29 changes: 29 additions & 0 deletions crates/libs/metadata/src/writer/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
mod blobs;
mod gen;
mod helpers;
mod pe;
mod strings;
mod tables;
use blobs::*;

pub use gen::*;
use helpers::*;
use std::collections::*;
use strings::*;
use tables::*;

pub fn test() {
let mut tables = Tables::new();
tables.module.push(Module::new("test.winmd"));
tables.type_def.push(TypeDef::module());

let mut stringable = TypeDef::winrt_interface("IStringable", "Windows.Foundation");
stringable.method_list.push(MethodDef::new("ToString"));
tables.type_def.push(stringable);

let mut closable = TypeDef::winrt_interface("IClosable", "Windows.Foundation");
closable.method_list.push(MethodDef::new("Close"));
tables.type_def.push(closable);

pe::write("/git/test.winmd", tables);
}
Loading

0 comments on commit b3ebe39

Please sign in to comment.