-
Notifications
You must be signed in to change notification settings - Fork 503
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
Basic metadata generation #1820
Changes from 4 commits
89cf3ad
928588c
49fc829
dab1f1a
470adf7
01c5023
21d6c9a
f9855ee
131a2d4
8e886ad
8625eef
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,19 @@ | ||
#[derive(Default)] | ||
pub struct FieldAttributes(pub usize); | ||
|
||
#[derive(Default)] | ||
pub struct MethodAttributes(pub usize); | ||
|
||
#[derive(Default)] | ||
pub struct MethodImplAttributes(pub usize); | ||
|
||
#[derive(Default)] | ||
pub struct ParamAttributes(pub usize); | ||
|
||
#[derive(Default)] | ||
pub struct PInvokeAttributes(pub usize); | ||
|
||
#[derive(Default)] | ||
pub struct TypeAttributes(pub usize); | ||
|
||
impl FieldAttributes { | ||
|
@@ -42,13 +53,38 @@ impl PInvokeAttributes { | |
} | ||
|
||
impl TypeAttributes { | ||
pub fn union(&self) -> bool { | ||
pub fn public(&self) -> bool { | ||
self.0 & 0x1 != 0 | ||
} | ||
pub fn set_public(&mut self) { | ||
self.0 |= 0x1; | ||
} | ||
|
||
pub fn explicit_layout(&self) -> bool { | ||
self.0 & 0x10 != 0 | ||
} | ||
pub fn set_explicit_layout(&mut self) { | ||
self.0 |= 0x10; | ||
} | ||
|
||
pub fn get_abstract(&self) -> bool { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: It would be more consistent to just call this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unfortunately, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah that's a shame. You could use it by doing |
||
self.0 & 0x80 != 0 | ||
} | ||
pub fn set_abstract(&mut self) { | ||
self.0 |= 0x80; | ||
} | ||
|
||
pub fn winrt(&self) -> bool { | ||
self.0 & 0x4000 != 0 | ||
} | ||
pub fn set_winrt(&mut self) { | ||
self.0 |= 0x4000; | ||
} | ||
|
||
pub fn interface(&self) -> bool { | ||
self.0 & 0x20 != 0 | ||
} | ||
pub fn set_interface(&mut self) { | ||
self.0 |= 0x20 | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
mod flags; | ||
|
||
pub use flags::*; |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,45 @@ | ||||||||||||||||||||||
#[repr(C)] | ||||||||||||||||||||||
#[derive(Default)] | ||||||||||||||||||||||
pub struct METADATA_HEADER { | ||||||||||||||||||||||
pub signature: u32, | ||||||||||||||||||||||
pub major_version: u16, | ||||||||||||||||||||||
pub minor_version: u16, | ||||||||||||||||||||||
pub reserved: u32, | ||||||||||||||||||||||
pub length: u32, | ||||||||||||||||||||||
pub version: [u8; 20], | ||||||||||||||||||||||
pub flags: u16, | ||||||||||||||||||||||
pub streams: u16, | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
pub const METADATA_SIGNATURE: u32 = 0x424A_5342; | ||||||||||||||||||||||
|
||||||||||||||||||||||
extern "C" { | ||||||||||||||||||||||
pub fn strlen(cs: *const u8) -> usize; | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
pub fn composite_index_size(tables: &[usize]) -> usize { | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know this function requires a deep understanding of the metadata file format, but I do think some small comments could make this much easier to understand. |
||||||||||||||||||||||
fn small(row_count: usize, bits: u8) -> bool { | ||||||||||||||||||||||
(row_count as u64) < (1u64 << (16 - bits)) | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
fn bits_needed(value: usize) -> u8 { | ||||||||||||||||||||||
let mut value = value - 1; | ||||||||||||||||||||||
let mut bits: u8 = 1; | ||||||||||||||||||||||
loop { | ||||||||||||||||||||||
value >>= 1; | ||||||||||||||||||||||
if value == 0 { | ||||||||||||||||||||||
break; | ||||||||||||||||||||||
} | ||||||||||||||||||||||
bits += 1; | ||||||||||||||||||||||
} | ||||||||||||||||||||||
Comment on lines
+28
to
+34
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. wow that's cool |
||||||||||||||||||||||
bits | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
let bits_needed = bits_needed(tables.len()); | ||||||||||||||||||||||
|
||||||||||||||||||||||
if tables.iter().all(|table| small(*table, bits_needed)) { | ||||||||||||||||||||||
2 | ||||||||||||||||||||||
} else { | ||||||||||||||||||||||
4 | ||||||||||||||||||||||
} | ||||||||||||||||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,55 +1,13 @@ | ||
#![allow(dead_code)] | ||
|
||
use std::collections::*; | ||
mod common; | ||
mod imp; | ||
pub mod reader; | ||
pub mod writer; | ||
|
||
pub use common::*; | ||
use imp::*; | ||
use std::io::*; | ||
use std::mem::*; | ||
use std::ptr::*; | ||
|
||
#[repr(C)] | ||
#[derive(Default)] | ||
struct METADATA_HEADER { | ||
signature: u32, | ||
major_version: u16, | ||
minor_version: u16, | ||
reserved: u32, | ||
length: u32, | ||
version: [u8; 20], | ||
flags: u16, | ||
streams: u16, | ||
} | ||
|
||
const METADATA_SIGNATURE: u32 = 0x424A_5342; | ||
|
||
extern "C" { | ||
fn strlen(cs: *const u8) -> usize; | ||
} | ||
|
||
fn composite_index_size(tables: &[usize]) -> usize { | ||
fn small(row_count: usize, bits: u8) -> bool { | ||
(row_count as u64) < (1u64 << (16 - bits)) | ||
} | ||
|
||
fn bits_needed(value: usize) -> u8 { | ||
let mut value = value - 1; | ||
let mut bits: u8 = 1; | ||
loop { | ||
value >>= 1; | ||
if value == 0 { | ||
break; | ||
} | ||
bits += 1; | ||
} | ||
bits | ||
} | ||
|
||
let bits_needed = bits_needed(tables.len()); | ||
|
||
if tables.iter().all(|table| small(*table, bits_needed)) { | ||
2 | ||
} else { | ||
4 | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,29 +1,15 @@ | ||
mod blobs; | ||
mod gen; | ||
mod helpers; | ||
mod pe; | ||
pub mod pe; | ||
mod strings; | ||
mod tables; | ||
use blobs::*; | ||
mod type_name; | ||
|
||
use super::*; | ||
use blobs::*; | ||
pub use gen::*; | ||
use helpers::*; | ||
pub use helpers::*; | ||
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); | ||
} | ||
pub use tables::*; | ||
pub use type_name::*; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the difference between
gen.reader.type_def_has_explicit_layout(def)
andgen.reader.type_def_flags(def).explicit_layout()
. If they're equivalent, could we stick with using just one?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
explicit_layout
flag just checks the bit in theTypeDef
record. Thetype_def_has_explicit_layout
is a much more comprehensive inspection that checks not only theTypeDef
itself, but also its fields recursively, and also any otherTypeDef
s of the same type but for different architectures. The latter depends on the former.