tpit patch
This commit is contained in:
parent
c7d4e8ded3
commit
fbb61e4a94
116
pit-core/src/info.rs
Normal file
116
pit-core/src/info.rs
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
use std::{collections::BTreeMap, fmt::Display};
|
||||||
|
|
||||||
|
use nom::{
|
||||||
|
bytes::complete::{tag, take_while_m_n}, character::complete::{alphanumeric1, multispace0}, multi::many0, sequence::delimited, IResult
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::{merge, parse_attr, Attr};
|
||||||
|
#[derive(Default,Clone)]
|
||||||
|
pub struct Info {
|
||||||
|
pub interfaces: BTreeMap<[u8; 32], InfoEntry>,
|
||||||
|
}
|
||||||
|
impl Info{
|
||||||
|
pub fn merge(self, x: Info) -> Info{
|
||||||
|
let mut m: BTreeMap<[u8;32],InfoEntry> = BTreeMap::new();
|
||||||
|
for (a,b) in self.interfaces.into_iter().chain(x.interfaces.into_iter()){
|
||||||
|
let c = m.remove(&a).unwrap_or_default().merge(b);
|
||||||
|
m.insert(a, c);
|
||||||
|
}
|
||||||
|
Info { interfaces: m }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[derive(Default,Clone)]
|
||||||
|
pub struct InfoEntry {
|
||||||
|
pub attrs: Vec<Attr>,
|
||||||
|
pub methods: BTreeMap<String,MethEntry>
|
||||||
|
}
|
||||||
|
impl InfoEntry{
|
||||||
|
pub fn merge(self, x: InfoEntry) -> InfoEntry{
|
||||||
|
let mut m: BTreeMap<String, MethEntry> = BTreeMap::new();
|
||||||
|
for (a,b) in self.methods.into_iter().chain(x.methods.into_iter()){
|
||||||
|
let c = m.remove(&a).unwrap_or_default().merge(b);
|
||||||
|
m.insert(a, c);
|
||||||
|
}
|
||||||
|
InfoEntry { attrs: merge(self.attrs, x.attrs), methods: m }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[derive(Default,Clone)]
|
||||||
|
pub struct MethEntry{
|
||||||
|
pub attrs: Vec<Attr>
|
||||||
|
}
|
||||||
|
impl MethEntry{
|
||||||
|
pub fn merge(self, x: MethEntry) -> MethEntry{
|
||||||
|
MethEntry { attrs: merge(self.attrs, x.attrs) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Display for InfoEntry {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
for a in self.attrs.iter(){
|
||||||
|
write!(f,"root {a}")?;
|
||||||
|
}
|
||||||
|
for (k,m) in self.methods.iter(){
|
||||||
|
for a in m.attrs.iter(){
|
||||||
|
write!(f,"method {k} {a}")?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Display for Info {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
for (i, j) in self.interfaces.iter() {
|
||||||
|
write!(f, "{}: [{j}]", hex::encode(i))?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn parse_entry(a: &str) -> IResult<&str, InfoEntry> {
|
||||||
|
let (a,_) = multispace0(a)?;
|
||||||
|
pub fn go1(a: &str) -> IResult<&str,Attr>{
|
||||||
|
let (a,_) = multispace0(a)?;
|
||||||
|
let (a,_) = tag("root")(a)?;
|
||||||
|
let (a,_) = multispace0(a)?;
|
||||||
|
return parse_attr(a);
|
||||||
|
}
|
||||||
|
pub fn go2(a: &str) -> IResult<&str,(&str,Attr)>{
|
||||||
|
let (a,_) = multispace0(a)?;
|
||||||
|
let (a,_) = tag("method")(a)?;
|
||||||
|
let (a,_) = multispace0(a)?;
|
||||||
|
let (a,b) = alphanumeric1(a)?;
|
||||||
|
let (a,_) = multispace0(a)?;
|
||||||
|
let (a,c) = parse_attr(a)?;
|
||||||
|
Ok((a,(b,c)))
|
||||||
|
}
|
||||||
|
let (a,mut e) = many0(go1)(a)?;
|
||||||
|
e.sort_by_key(|k|k.name.clone());
|
||||||
|
let mut n: BTreeMap<String, MethEntry> = BTreeMap::new();
|
||||||
|
let (a,l) = many0(go2)(a)?;
|
||||||
|
for (k,v) in l{
|
||||||
|
n.entry(k.to_owned()).or_insert_with(Default::default).attrs.push(v);
|
||||||
|
}
|
||||||
|
for v in n.values_mut(){
|
||||||
|
v.attrs.sort_by_key(|k|k.name.clone());
|
||||||
|
}
|
||||||
|
let (a,_) = multispace0(a)?;
|
||||||
|
Ok((a, InfoEntry { attrs: e, methods: n }))
|
||||||
|
}
|
||||||
|
pub fn parse_info(a: &str) -> IResult<&str, Info> {
|
||||||
|
pub fn go(a: &str) -> IResult<&str, ([u8; 32], InfoEntry)> {
|
||||||
|
let (a,_) = multispace0(a)?;
|
||||||
|
let (a, d) = take_while_m_n(64, 64, |a: char| a.is_digit(16))(a)?;
|
||||||
|
let mut b = [0u8; 32];
|
||||||
|
hex::decode_to_slice(d, &mut b).unwrap();
|
||||||
|
let (a,_) = multispace0(a)?;
|
||||||
|
let (a,_) = tag(":")(a)?;
|
||||||
|
let (a,_) = multispace0(a)?;
|
||||||
|
let (a, c) = delimited(tag("["), parse_entry, tag("]"))(a)?;
|
||||||
|
return Ok((a, (b, c)));
|
||||||
|
}
|
||||||
|
let (a, all) = many0(go)(a)?;
|
||||||
|
Ok((
|
||||||
|
a,
|
||||||
|
Info {
|
||||||
|
interfaces: all.into_iter().collect(),
|
||||||
|
},
|
||||||
|
))
|
||||||
|
}
|
|
@ -16,6 +16,14 @@ pub struct Attr {
|
||||||
pub value: String,
|
pub value: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn merge(a: Vec<Attr>, b: Vec<Attr>) -> Vec<Attr>{
|
||||||
|
let mut m = BTreeMap::new();
|
||||||
|
for x in a.into_iter().chain(b){
|
||||||
|
m.insert(x.name, x.value);
|
||||||
|
}
|
||||||
|
return m.into_iter().map(|(a,b)|Attr{name: a,value: b}).collect();
|
||||||
|
}
|
||||||
|
|
||||||
pub fn parse_balanced(mut a: &str) -> IResult<&str, String> {
|
pub fn parse_balanced(mut a: &str) -> IResult<&str, String> {
|
||||||
let mut v = vec![];
|
let mut v = vec![];
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
|
@ -244,3 +252,4 @@ impl Interface {
|
||||||
return hex::encode(self.rid());
|
return hex::encode(self.rid());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub mod info;
|
|
@ -142,7 +142,7 @@ pub fn tfree(m: &mut Module, t: Table) -> anyhow::Result<Func> {
|
||||||
|
|
||||||
// use waffle::{util::new_sig, Module};
|
// use waffle::{util::new_sig, Module};
|
||||||
|
|
||||||
pub fn to_waffle_type(t: &pit_core::Arg) -> waffle::Type {
|
pub fn to_waffle_type(t: &pit_core::Arg, tpit: bool) -> waffle::Type {
|
||||||
match t {
|
match t {
|
||||||
pit_core::Arg::I32 => waffle::Type::I32,
|
pit_core::Arg::I32 => waffle::Type::I32,
|
||||||
pit_core::Arg::I64 => waffle::Type::I64,
|
pit_core::Arg::I64 => waffle::Type::I64,
|
||||||
|
@ -153,24 +153,32 @@ pub fn to_waffle_type(t: &pit_core::Arg) -> waffle::Type {
|
||||||
nullable,
|
nullable,
|
||||||
take,
|
take,
|
||||||
ann,
|
ann,
|
||||||
} => waffle::Type::ExternRef,
|
} => if tpit{
|
||||||
|
waffle::Type::I32
|
||||||
|
}else{
|
||||||
|
waffle::Type::ExternRef
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn to_waffle_sig(m: &mut Module, t: &pit_core::Sig) -> waffle::Signature {
|
pub fn to_waffle_sig(m: &mut Module, t: &pit_core::Sig, tpit: bool,) -> waffle::Signature {
|
||||||
return new_sig(
|
return new_sig(
|
||||||
m,
|
m,
|
||||||
waffle::SignatureData {
|
waffle::SignatureData {
|
||||||
params: t.params.iter().map(to_waffle_type).collect(),
|
params: t.params.iter().map(|a|to_waffle_type(a,tpit)).collect(),
|
||||||
returns: t.rets.iter().map(to_waffle_type).collect(),
|
returns: t.rets.iter().map(|a|to_waffle_type(a,tpit)).collect(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
pub fn waffle_funcs(m: &mut Module, i: &pit_core::Interface) -> BTreeMap<String, Func> {
|
pub fn waffle_funcs(m: &mut Module, i: &pit_core::Interface, tpit: bool,) -> BTreeMap<String, Func> {
|
||||||
return i
|
return i
|
||||||
.methods
|
.methods
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(a, b)| {
|
.map(|(a, b)| {
|
||||||
let module = format!("pit/{}", i.rid_str());
|
let module = format!("{}pit/{}", i.rid_str(), if tpit{
|
||||||
|
"t"
|
||||||
|
}else{
|
||||||
|
""
|
||||||
|
});
|
||||||
let name = a.clone();
|
let name = a.clone();
|
||||||
if let Some(f) = m.imports.iter().find_map(|i| {
|
if let Some(f) = m.imports.iter().find_map(|i| {
|
||||||
if i.module == module && i.name == name {
|
if i.module == module && i.name == name {
|
||||||
|
@ -184,7 +192,7 @@ pub fn waffle_funcs(m: &mut Module, i: &pit_core::Interface) -> BTreeMap<String,
|
||||||
}) {
|
}) {
|
||||||
return (a.clone(), f);
|
return (a.clone(), f);
|
||||||
};
|
};
|
||||||
let s = to_waffle_sig(m, b);
|
let s = to_waffle_sig(m, b,tpit);
|
||||||
let f = m
|
let f = m
|
||||||
.funcs
|
.funcs
|
||||||
.push(waffle::FuncDecl::Import(s, format!("{module}.{name}")));
|
.push(waffle::FuncDecl::Import(s, format!("{module}.{name}")));
|
||||||
|
@ -432,10 +440,46 @@ pub fn wrap(m: &mut Module) -> anyhow::Result<()> {
|
||||||
m.funcs[o] = FuncDecl::Body(s, format!("_pit"), b);
|
m.funcs[o] = FuncDecl::Body(s, format!("_pit"), b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if let Some(a) = import.name.strip_suffix(".tpit-res").map(|a|a.to_owned()){
|
||||||
|
import.name = a;
|
||||||
|
if let ImportKind::Func(f) = &mut import.kind {
|
||||||
|
let p = m.signatures[m.funcs[*f].sig()].params.clone();
|
||||||
|
let p = new_sig(
|
||||||
|
m,
|
||||||
|
SignatureData {
|
||||||
|
params: p,
|
||||||
|
returns: vec![Type::I32],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
let p = m.funcs.push(waffle::FuncDecl::Import(p, format!("_pit")));
|
||||||
|
let s = m.funcs[*f].sig();
|
||||||
|
let o = replace(f, p);
|
||||||
|
let mut b = FunctionBody::new(&m, s);
|
||||||
|
let e = b.entry;
|
||||||
|
let arg = b.blocks[b.entry].params.iter().map(|a|a.1).collect::<Vec<_>>();
|
||||||
|
let arg = add_op(
|
||||||
|
&mut b,
|
||||||
|
&arg,
|
||||||
|
&[Type::ExternRef],
|
||||||
|
Operator::Call {
|
||||||
|
function_index: p,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
b.append_to_block(e, arg);
|
||||||
|
b.set_terminator(
|
||||||
|
e,
|
||||||
|
waffle::Terminator::ReturnCall {
|
||||||
|
func: talloc,
|
||||||
|
args: vec![arg],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
m.funcs[o] = FuncDecl::Body(s, format!("_pit"), b);
|
||||||
|
}
|
||||||
|
}
|
||||||
m.imports.push(import);
|
m.imports.push(import);
|
||||||
}
|
}
|
||||||
for i in is {
|
for i in is {
|
||||||
let f = waffle_funcs(m, &i);
|
let f = waffle_funcs(m, &i,false);
|
||||||
for mut import in take(&mut m.imports) {
|
for mut import in take(&mut m.imports) {
|
||||||
if import.module == format!("tpit/{}", i.rid_str()) {
|
if import.module == format!("tpit/{}", i.rid_str()) {
|
||||||
match import.name.strip_prefix("~") {
|
match import.name.strip_prefix("~") {
|
||||||
|
@ -476,7 +520,7 @@ pub fn wrap(m: &mut Module) -> anyhow::Result<()> {
|
||||||
.methods
|
.methods
|
||||||
.get(&import.name)
|
.get(&import.name)
|
||||||
.context("in getting the method")?;
|
.context("in getting the method")?;
|
||||||
let p = to_waffle_sig(m, x);
|
let p = to_waffle_sig(m, x,false);
|
||||||
let p = m.signatures[p].clone();
|
let p = m.signatures[p].clone();
|
||||||
let p = new_sig(
|
let p = new_sig(
|
||||||
m,
|
m,
|
||||||
|
@ -558,7 +602,7 @@ pub fn wrap(m: &mut Module) -> anyhow::Result<()> {
|
||||||
}
|
}
|
||||||
Some((a, b)) => {
|
Some((a, b)) => {
|
||||||
let x = i.methods.get(b).context("in getting the method")?;
|
let x = i.methods.get(b).context("in getting the method")?;
|
||||||
let p = to_waffle_sig(m, x);
|
let p = to_waffle_sig(m, x,false);
|
||||||
let p = m.signatures[p].clone();
|
let p = m.signatures[p].clone();
|
||||||
let p = new_sig(
|
let p = new_sig(
|
||||||
m,
|
m,
|
||||||
|
|
Loading…
Reference in a new issue