Skip to content

Commit ed7f735

Browse files
committed
feat(xlang-ir): Add RequiredMetadata metadata
1 parent 9cf0798 commit ed7f735

File tree

6 files changed

+120
-11
lines changed

6 files changed

+120
-11
lines changed

xlang/xlang_struct/Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ ABI Safe structures for representing xlang's intermediate representation
1111
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
1212

1313
[dependencies]
14-
xlang_abi = {path="../xlang_abi",version="0.2.0"}
15-
xlang_targets = {path="../xlang_targets",version="0.2.0"}
16-
bitflags = "1.3"
14+
xlang_abi = { path = "../xlang_abi", version = "0.2.0" }
15+
xlang_targets = { path = "../xlang_targets", version = "0.2.0" }
16+
bitflags.workspace = true
1717
fake-enum = "0.1.4"

xlang/xlang_struct/src/lib.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,7 @@ bitflags::bitflags! {
414414
/// static-specifier := "immut"
415415
/// ```
416416
#[repr(transparent)]
417+
#[derive(Default, Copy, Clone, Debug, Hash, PartialEq, Eq)]
417418
pub struct StaticSpecifier : u16{
418419
const IMMUTABLE = 0x001;
419420
}
@@ -478,7 +479,7 @@ bitflags::bitflags! {
478479
/// `uninit` is considered invalid for any scalar type that has any validity constraint - loading/storing such a value yields `invalid`.
479480
///
480481
#[repr(transparent)]
481-
#[derive(Default)]
482+
#[derive(Default, Copy, Clone, Debug, Hash, PartialEq, Eq)]
482483
pub struct ScalarValidity : u8{
483484
/// The `scalar-validity` specifier `"nonzero"`.
484485
/// Indicates that a zero value is not permitted.
@@ -522,6 +523,7 @@ bitflags::bitflags! {
522523
/// char-specifier := ["unicode"]
523524
/// ```
524525
#[repr(transparent)]
526+
#[derive(Default, Copy, Clone, Debug, Hash, PartialEq, Eq)]
525527
pub struct CharFlags: u8{
526528
/// Whether or not the type is considered to be signed or unsigned
527529
///
@@ -1027,6 +1029,7 @@ bitflags::bitflags! {
10271029
/// field-specifier := "mutable"
10281030
/// ```
10291031
#[repr(transparent)]
1032+
#[derive(Default, Copy, Clone, Debug, Hash, PartialEq, Eq)]
10301033
pub struct AggregateFieldSpecifier : u32{
10311034
/// Indicates that the field is writable, regardless of `readonly`, `readshallow`, or top level `immutable binding`
10321035
const MUTABLE = 0x0001;
@@ -1160,7 +1163,7 @@ bitflags::bitflags! {
11601163
/// pointer-aliasing = "unique" / "readonly" / "nonnull"
11611164
/// ```
11621165
#[repr(transparent)]
1163-
#[derive(Default)]
1166+
#[derive(Default, Copy, Clone, Debug, Hash, PartialEq, Eq)]
11641167
pub struct PointerAliasingRule : u32{
11651168
/// Indicates that no other pointers access any of the same bytes while this pointer is active.
11661169
///
@@ -1215,7 +1218,7 @@ bitflags::bitflags! {
12151218
/// ```
12161219
///
12171220
#[repr(transparent)]
1218-
#[derive(Default)]
1221+
#[derive(Default, Copy, Clone, Debug, Hash, PartialEq, Eq)]
12191222
pub struct ValidRangeType : u16{
12201223
/// Indicates that the valid range of the pointer
12211224
const INBOUNDS = 1;
@@ -1225,7 +1228,7 @@ bitflags::bitflags! {
12251228
}
12261229
bitflags::bitflags! {
12271230
#[repr(transparent)]
1228-
#[derive(Default)]
1231+
#[derive(Default, Copy, Clone, Debug, Hash, PartialEq, Eq)]
12291232
pub struct PointerDeclarationType : u16{
12301233
const REF = 1;
12311234
const CONST = 2;
@@ -2267,7 +2270,7 @@ bitflags::bitflags! {
22672270
/// jump-target-flag := "fallthrough" / "cold" / "continue"
22682271
/// ```
22692272
#[repr(transparent)]
2270-
#[derive(Default)]
2273+
#[derive(Default, Copy, Clone, Debug, Hash, PartialEq, Eq)]
22712274
pub struct JumpTargetFlags : u32{
22722275
/// The "fallthrough" flag.
22732276
/// Indicates that the jump does not perform a branch but instead continues on to the next basic block
@@ -2319,6 +2322,7 @@ impl core::fmt::Display for JumpTarget {
23192322
bitflags::bitflags! {
23202323
/// Flags for the call instruction
23212324
#[repr(transparent)]
2325+
#[derive(Default, Copy, Clone, Debug, Hash, PartialEq, Eq)]
23222326
pub struct CallFlags: u32{
23232327
/// Indicates the the call or tailcall will definitely return in finite time
23242328
const WILLRETURN = 1;
@@ -2384,6 +2388,7 @@ impl core::fmt::Display for AsmConstraint {
23842388

23852389
bitflags::bitflags! {
23862390
#[repr(transparent)]
2391+
#[derive(Default, Copy, Clone, Debug, Hash, PartialEq, Eq)]
23872392
// more like clippy::readable_literal
23882393
pub struct AsmOptions : u32{
23892394
#[allow(clippy::unreadable_literal)]

xlang/xlang_struct/src/meta.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ use xlang_abi::prelude::v1::*;
99
use xlang_abi::result::Result::{self, Ok};
1010

1111
pub mod block;
12+
pub mod body;
13+
pub mod file;
1214

1315
#[repr(C)]
1416
#[cfg_attr(target_pointer_width = "32", repr(align(32)))]
@@ -169,15 +171,15 @@ impl<T> Metadata<T> {
169171
}
170172
}
171173

172-
pub fn get<M: MetadataFor<T>>(&self) -> Option<&T> {
174+
pub fn get<M: MetadataFor<T>>(&self) -> Option<&M> {
173175
if self.ty == M::TAG {
174176
Some(unsafe { transmute_unchecked(&self.data) })
175177
} else {
176178
None
177179
}
178180
}
179181

180-
pub fn get_mut<M: MetadataFor<T>>(&mut self) -> Option<&mut T> {
182+
pub fn get_mut<M: MetadataFor<T>>(&mut self) -> Option<&mut M> {
181183
if self.ty == M::TAG {
182184
Some(unsafe { transmute_unchecked(&mut self.data) })
183185
} else {
@@ -276,6 +278,14 @@ impl<T> MetadataList<T> {
276278
pub fn push<M: Into<Metadata<T>>>(&mut self, m: M) {
277279
self.0.push(m.into())
278280
}
281+
282+
pub fn get<M: MetadataFor<T>>(&self) -> Option<&M> {
283+
self.0.iter().find_map(Metadata::get)
284+
}
285+
286+
pub fn get_mut<M: MetadataFor<T>>(&mut self) -> Option<&mut M> {
287+
self.0.iter_mut().find_map(Metadata::get_mut)
288+
}
279289
}
280290

281291
impl<T, A: Into<Metadata<T>>> core::iter::FromIterator<A> for MetadataList<T> {

xlang/xlang_struct/src/meta/block.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,19 @@ use crate::Block;
33

44
use xlang_abi::prelude::v1::*;
55

6-
#[derive(Clone, Debug)]
6+
#[derive(Clone, Debug, Default)]
77
pub struct ReachableFrom {
88
pub reachable: Vec<u32>,
99
}
1010

11+
impl ReachableFrom {
12+
pub const fn new() -> Self {
13+
Self {
14+
reachable: Vec::new(),
15+
}
16+
}
17+
}
18+
1119
impl core::fmt::Display for ReachableFrom {
1220
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1321
let mut sep = "";

xlang/xlang_struct/src/meta/body.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

xlang/xlang_struct/src/meta/file.rs

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
use xlang_abi::string::{CowStr, StringView};
2+
3+
use crate::File;
4+
5+
use crate::meta::MetadataFor;
6+
7+
#[repr(C)]
8+
#[derive(Clone, Debug)]
9+
pub struct RequiredMetadata {
10+
pub meta: Vec<RequiresEntry>,
11+
}
12+
13+
impl super::sealed::Sealed for RequiredMetadata {}
14+
15+
impl MetadataFor<File> for RequiredMetadata {
16+
const TAG: StringView<'static> = StringView::new("requires");
17+
}
18+
19+
impl core::fmt::Display for RequiredMetadata {
20+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
21+
let mut sep = "";
22+
23+
for m in &self.meta {
24+
f.write_str(sep)?;
25+
sep = ", ";
26+
m.fmt(f)?;
27+
}
28+
Ok(())
29+
}
30+
}
31+
32+
bitflags::bitflags! {
33+
#[repr(transparent)]
34+
#[derive(Default, Copy, Clone, Debug, Hash, PartialEq, Eq)]
35+
pub struct RequiredMetadataContext : u32{
36+
/// Any plugin that views the incoming IR *must* not process a file that sets the metadata type it doesn't recognize
37+
/// (Metadata is mandatory for interpreting the file at all)
38+
const PROCESSOR = 0x00000001;
39+
/// An output plugin (code generator) must not process a file that sets the metadata type it doesn't recognize
40+
/// (Metadata is mandatory for emitting code from the metadata)
41+
const OUTPUT = 0x00000002;
42+
/// Any plugin that mutates the incoming IR in place must not process a file that sets the metadata type it doesn't recognize
43+
const TRANSFORMER = 0x00000004;
44+
/// Any transformer plugin that is an optimizer must not process a file that sets the metadata type it doesn't recognize
45+
const OPTIMIZER = 0x00000008;
46+
}
47+
}
48+
49+
bitflags::bitflags! {
50+
#[repr(transparent)]
51+
#[derive(Default, Copy, Clone, Debug, Hash, PartialEq, Eq)]
52+
pub struct RequiredMetadataPosition : u128{
53+
const FILE = 0x0001;
54+
}
55+
}
56+
57+
#[repr(C)]
58+
#[derive(Clone, Debug)]
59+
pub struct RequiresEntry {
60+
pub key: CowStr<'static>,
61+
pub ctx: RequiredMetadataContext,
62+
pub positions: RequiredMetadataPosition,
63+
}
64+
65+
impl core::fmt::Display for RequiresEntry {
66+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
67+
f.write_str(self.key.as_str())?;
68+
f.write_str(" ")?;
69+
70+
for (name, _) in self.ctx.iter_names() {
71+
f.write_str(&name.to_ascii_lowercase())?;
72+
f.write_str(" ")?;
73+
}
74+
75+
let mut sep = "";
76+
f.write_str("{")?;
77+
for (pos, _) in self.positions.iter_names() {
78+
f.write_str(sep)?;
79+
sep = ", ";
80+
f.write_str(&pos.to_ascii_lowercase())?;
81+
}
82+
83+
f.write_str("}")
84+
}
85+
}

0 commit comments

Comments
 (0)