Skip to content

Commit

Permalink
feat(xlang-ir): Add RequiredMetadata metadata
Browse files Browse the repository at this point in the history
chorman0773 committed Nov 13, 2024
1 parent 9cf0798 commit ed7f735
Showing 6 changed files with 120 additions and 11 deletions.
6 changes: 3 additions & 3 deletions xlang/xlang_struct/Cargo.toml
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@ ABI Safe structures for representing xlang's intermediate representation
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
xlang_abi = {path="../xlang_abi",version="0.2.0"}
xlang_targets = {path="../xlang_targets",version="0.2.0"}
bitflags = "1.3"
xlang_abi = { path = "../xlang_abi", version = "0.2.0" }
xlang_targets = { path = "../xlang_targets", version = "0.2.0" }
bitflags.workspace = true
fake-enum = "0.1.4"
15 changes: 10 additions & 5 deletions xlang/xlang_struct/src/lib.rs
Original file line number Diff line number Diff line change
@@ -414,6 +414,7 @@ bitflags::bitflags! {
/// static-specifier := "immut"
/// ```
#[repr(transparent)]
#[derive(Default, Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub struct StaticSpecifier : u16{
const IMMUTABLE = 0x001;
}
@@ -478,7 +479,7 @@ bitflags::bitflags! {
/// `uninit` is considered invalid for any scalar type that has any validity constraint - loading/storing such a value yields `invalid`.
///
#[repr(transparent)]
#[derive(Default)]
#[derive(Default, Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub struct ScalarValidity : u8{
/// The `scalar-validity` specifier `"nonzero"`.
/// Indicates that a zero value is not permitted.
@@ -522,6 +523,7 @@ bitflags::bitflags! {
/// char-specifier := ["unicode"]
/// ```
#[repr(transparent)]
#[derive(Default, Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub struct CharFlags: u8{
/// Whether or not the type is considered to be signed or unsigned
///
@@ -1027,6 +1029,7 @@ bitflags::bitflags! {
/// field-specifier := "mutable"
/// ```
#[repr(transparent)]
#[derive(Default, Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub struct AggregateFieldSpecifier : u32{
/// Indicates that the field is writable, regardless of `readonly`, `readshallow`, or top level `immutable binding`
const MUTABLE = 0x0001;
@@ -1160,7 +1163,7 @@ bitflags::bitflags! {
/// pointer-aliasing = "unique" / "readonly" / "nonnull"
/// ```
#[repr(transparent)]
#[derive(Default)]
#[derive(Default, Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub struct PointerAliasingRule : u32{
/// Indicates that no other pointers access any of the same bytes while this pointer is active.
///
@@ -1215,7 +1218,7 @@ bitflags::bitflags! {
/// ```
///
#[repr(transparent)]
#[derive(Default)]
#[derive(Default, Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub struct ValidRangeType : u16{
/// Indicates that the valid range of the pointer
const INBOUNDS = 1;
@@ -1225,7 +1228,7 @@ bitflags::bitflags! {
}
bitflags::bitflags! {
#[repr(transparent)]
#[derive(Default)]
#[derive(Default, Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub struct PointerDeclarationType : u16{
const REF = 1;
const CONST = 2;
@@ -2267,7 +2270,7 @@ bitflags::bitflags! {
/// jump-target-flag := "fallthrough" / "cold" / "continue"
/// ```
#[repr(transparent)]
#[derive(Default)]
#[derive(Default, Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub struct JumpTargetFlags : u32{
/// The "fallthrough" flag.
/// 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 {
bitflags::bitflags! {
/// Flags for the call instruction
#[repr(transparent)]
#[derive(Default, Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub struct CallFlags: u32{
/// Indicates the the call or tailcall will definitely return in finite time
const WILLRETURN = 1;
@@ -2384,6 +2388,7 @@ impl core::fmt::Display for AsmConstraint {

bitflags::bitflags! {
#[repr(transparent)]
#[derive(Default, Copy, Clone, Debug, Hash, PartialEq, Eq)]
// more like clippy::readable_literal
pub struct AsmOptions : u32{
#[allow(clippy::unreadable_literal)]
14 changes: 12 additions & 2 deletions xlang/xlang_struct/src/meta.rs
Original file line number Diff line number Diff line change
@@ -9,6 +9,8 @@ use xlang_abi::prelude::v1::*;
use xlang_abi::result::Result::{self, Ok};

pub mod block;
pub mod body;
pub mod file;

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

pub fn get<M: MetadataFor<T>>(&self) -> Option<&T> {
pub fn get<M: MetadataFor<T>>(&self) -> Option<&M> {
if self.ty == M::TAG {
Some(unsafe { transmute_unchecked(&self.data) })
} else {
None
}
}

pub fn get_mut<M: MetadataFor<T>>(&mut self) -> Option<&mut T> {
pub fn get_mut<M: MetadataFor<T>>(&mut self) -> Option<&mut M> {
if self.ty == M::TAG {
Some(unsafe { transmute_unchecked(&mut self.data) })
} else {
@@ -276,6 +278,14 @@ impl<T> MetadataList<T> {
pub fn push<M: Into<Metadata<T>>>(&mut self, m: M) {
self.0.push(m.into())
}

pub fn get<M: MetadataFor<T>>(&self) -> Option<&M> {
self.0.iter().find_map(Metadata::get)
}

pub fn get_mut<M: MetadataFor<T>>(&mut self) -> Option<&mut M> {
self.0.iter_mut().find_map(Metadata::get_mut)
}
}

impl<T, A: Into<Metadata<T>>> core::iter::FromIterator<A> for MetadataList<T> {
10 changes: 9 additions & 1 deletion xlang/xlang_struct/src/meta/block.rs
Original file line number Diff line number Diff line change
@@ -3,11 +3,19 @@ use crate::Block;

use xlang_abi::prelude::v1::*;

#[derive(Clone, Debug)]
#[derive(Clone, Debug, Default)]
pub struct ReachableFrom {
pub reachable: Vec<u32>,
}

impl ReachableFrom {
pub const fn new() -> Self {
Self {
reachable: Vec::new(),
}
}
}

impl core::fmt::Display for ReachableFrom {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut sep = "";
1 change: 1 addition & 0 deletions xlang/xlang_struct/src/meta/body.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

85 changes: 85 additions & 0 deletions xlang/xlang_struct/src/meta/file.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
use xlang_abi::string::{CowStr, StringView};

use crate::File;

use crate::meta::MetadataFor;

#[repr(C)]
#[derive(Clone, Debug)]
pub struct RequiredMetadata {
pub meta: Vec<RequiresEntry>,
}

impl super::sealed::Sealed for RequiredMetadata {}

impl MetadataFor<File> for RequiredMetadata {
const TAG: StringView<'static> = StringView::new("requires");
}

impl core::fmt::Display for RequiredMetadata {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut sep = "";

for m in &self.meta {
f.write_str(sep)?;
sep = ", ";
m.fmt(f)?;
}
Ok(())
}
}

bitflags::bitflags! {
#[repr(transparent)]
#[derive(Default, Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub struct RequiredMetadataContext : u32{
/// Any plugin that views the incoming IR *must* not process a file that sets the metadata type it doesn't recognize
/// (Metadata is mandatory for interpreting the file at all)
const PROCESSOR = 0x00000001;
/// An output plugin (code generator) must not process a file that sets the metadata type it doesn't recognize
/// (Metadata is mandatory for emitting code from the metadata)
const OUTPUT = 0x00000002;
/// Any plugin that mutates the incoming IR in place must not process a file that sets the metadata type it doesn't recognize
const TRANSFORMER = 0x00000004;
/// Any transformer plugin that is an optimizer must not process a file that sets the metadata type it doesn't recognize
const OPTIMIZER = 0x00000008;
}
}

bitflags::bitflags! {
#[repr(transparent)]
#[derive(Default, Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub struct RequiredMetadataPosition : u128{
const FILE = 0x0001;
}
}

#[repr(C)]
#[derive(Clone, Debug)]
pub struct RequiresEntry {
pub key: CowStr<'static>,
pub ctx: RequiredMetadataContext,
pub positions: RequiredMetadataPosition,
}

impl core::fmt::Display for RequiresEntry {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.key.as_str())?;
f.write_str(" ")?;

for (name, _) in self.ctx.iter_names() {
f.write_str(&name.to_ascii_lowercase())?;
f.write_str(" ")?;
}

let mut sep = "";
f.write_str("{")?;
for (pos, _) in self.positions.iter_names() {
f.write_str(sep)?;
sep = ", ";
f.write_str(&pos.to_ascii_lowercase())?;
}

f.write_str("}")
}
}

0 comments on commit ed7f735

Please sign in to comment.