1use crate::parser::{Interface, Type};
2
3pub mod export;
4pub mod import;
5
6#[derive(Clone, Copy, Debug)]
7pub enum NumType {
8 U8,
9 U16,
10 U32,
11 U64,
12 I8,
13 I16,
14 I32,
15 I64,
16 F32,
17 F64,
18}
19
20#[derive(Clone, Debug)]
21pub enum AbiType {
22 Num(NumType),
23 Usize,
24 Isize,
25 Bool,
26 RefStr,
27 String,
28 RefSlice(NumType),
29 Vec(NumType),
30 RefObject(String),
31 Object(String),
32 Option(Box<AbiType>),
33 Result(Box<AbiType>),
34 RefIter(Box<AbiType>),
35 Iter(Box<AbiType>),
36 RefFuture(Box<AbiType>),
37 Future(Box<AbiType>),
38 RefStream(Box<AbiType>),
39 Stream(Box<AbiType>),
40 Tuple(Vec<AbiType>),
41}
42
43impl AbiType {
44 pub fn num(&self) -> NumType {
45 if let Self::Num(num) = self {
46 *num
47 } else {
48 panic!()
49 }
50 }
51}
52
53#[derive(Clone, Debug)]
54pub enum FunctionType {
55 Constructor(String),
56 Method(String),
57 Function,
58 NextIter(String, AbiType),
59 PollFuture(String, AbiType),
60 PollStream(String, AbiType),
61}
62
63#[derive(Clone, Debug)]
64pub struct AbiFunction {
65 pub doc: Vec<String>,
66 pub ty: FunctionType,
67 pub name: String,
68 pub args: Vec<(String, AbiType)>,
69 pub ret: Option<AbiType>,
70}
71
72impl AbiFunction {
73 pub fn symbol(&self) -> String {
74 match &self.ty {
75 FunctionType::Constructor(object) | FunctionType::Method(object) => {
76 format!("__{}_{}", object, &self.name)
77 }
78 FunctionType::Function => format!("__{}", &self.name),
79 FunctionType::NextIter(symbol, _) => format!("{}_iter_{}", symbol, &self.name),
80 FunctionType::PollFuture(symbol, _) => format!("{}_future_{}", symbol, &self.name),
81 FunctionType::PollStream(symbol, _) => format!("{}_stream_{}", symbol, &self.name),
82 }
83 }
84
85 pub fn ret(&self, rets: Vec<Var>) -> Return {
86 match rets.len() {
87 0 => Return::Void,
88 1 => Return::Num(rets[0].clone()),
89 _ => Return::Struct(rets, format!("{}Return", self.symbol())),
90 }
91 }
92}
93
94#[derive(Clone, Debug)]
95pub struct AbiObject {
96 pub doc: Vec<String>,
97 pub name: String,
98 pub methods: Vec<AbiFunction>,
99 pub destructor: String,
100}
101
102#[derive(Clone, Debug)]
103pub struct AbiIter {
104 pub ty: AbiType,
105 pub symbol: String,
106}
107
108impl AbiIter {
109 pub fn next(&self) -> AbiFunction {
110 AbiFunction {
111 ty: FunctionType::NextIter(self.symbol.clone(), self.ty.clone()),
112 doc: vec![],
113 name: "next".to_string(),
114 args: vec![],
115 ret: Some(AbiType::Option(Box::new(self.ty.clone()))),
116 }
117 }
118}
119
120#[derive(Clone, Debug)]
121pub struct AbiFuture {
122 pub ty: AbiType,
123 pub symbol: String,
124}
125
126impl AbiFuture {
127 pub fn poll(&self) -> AbiFunction {
128 AbiFunction {
129 ty: FunctionType::PollFuture(self.symbol.clone(), self.ty.clone()),
130 doc: vec![],
131 name: "poll".to_string(),
132 args: vec![
133 ("post_cobject".to_string(), AbiType::Isize),
134 ("port".to_string(), AbiType::Num(NumType::I64)),
135 ],
136 ret: Some(AbiType::Option(Box::new(self.ty.clone()))),
137 }
138 }
139}
140
141#[derive(Clone, Debug)]
142pub struct AbiStream {
143 pub ty: AbiType,
144 pub symbol: String,
145}
146
147impl AbiStream {
148 pub fn poll(&self) -> AbiFunction {
149 AbiFunction {
150 ty: FunctionType::PollStream(self.symbol.clone(), self.ty.clone()),
151 doc: vec![],
152 name: "poll".to_string(),
153 args: vec![
154 ("post_cobject".to_string(), AbiType::Isize),
155 ("port".to_string(), AbiType::Num(NumType::I64)),
156 ("done".to_string(), AbiType::Num(NumType::I64)),
157 ],
158 ret: Some(AbiType::Option(Box::new(self.ty.clone()))),
159 }
160 }
161}
162
163#[derive(Clone, Debug)]
164pub enum Return {
165 Void,
166 Num(Var),
167 Struct(Vec<Var>, String),
168}
169
170#[derive(Default)]
171struct VarGen {
172 counter: u32,
173}
174
175impl VarGen {
176 pub fn new() -> Self {
177 Self::default()
178 }
179
180 pub fn gen_num(&mut self, num: NumType) -> Var {
181 self.gen(AbiType::Num(num))
182 }
183
184 pub fn gen(&mut self, ty: AbiType) -> Var {
185 let binding = self.counter;
186 self.counter += 1;
187 Var { binding, ty }
188 }
189}
190
191#[derive(Clone, Debug)]
192pub struct Var {
193 pub binding: u32,
194 pub ty: AbiType,
195}
196
197#[derive(Clone, Copy, Debug, Eq, PartialEq)]
199pub enum Abi {
200 Native32,
202 Native64,
204 Wasm32,
206 Wasm64,
208}
209
210impl Abi {
211 pub(crate) fn native() -> Self {
212 #[cfg(target_pointer_width = "32")]
213 return Abi::Native32;
214 #[cfg(target_pointer_width = "64")]
215 return Abi::Native64;
216 }
217
218 pub(crate) fn uptr(self) -> NumType {
219 match self {
220 Self::Native32 | Self::Wasm32 => NumType::U32,
221 Self::Native64 | Self::Wasm64 => NumType::U64,
222 }
223 }
224
225 pub(crate) fn iptr(self) -> NumType {
226 match self {
227 Self::Native32 | Self::Wasm32 => NumType::I32,
228 Self::Native64 | Self::Wasm64 => NumType::I64,
229 }
230 }
231
232 pub(crate) fn layout(self, ty: NumType) -> (usize, usize) {
234 let size = match ty {
235 NumType::U8 | NumType::I8 => 1,
236 NumType::U16 | NumType::I16 => 2,
237 NumType::U32 | NumType::I32 | NumType::F32 => 4,
238 NumType::U64 | NumType::I64 | NumType::F64 => 8,
239 };
240 let size = match self {
241 Self::Native32 | Self::Native64 => size,
242 Self::Wasm32 | Self::Wasm64 => core::cmp::max(4, size),
243 };
244 (size, size)
245 }
246}
247
248impl Interface {
249 pub fn objects(&self) -> Vec<AbiObject> {
250 let mut objs = vec![];
251 for object in &self.objects {
252 let mut methods = vec![];
253 for method in &object.methods {
254 let obj = object.ident.clone();
255 let func = AbiFunction {
256 doc: method.doc.clone(),
257 name: method.ident.clone(),
258 ty: if method.is_static {
259 FunctionType::Constructor(obj)
260 } else {
261 FunctionType::Method(obj)
262 },
263 args: method
264 .args
265 .iter()
266 .map(|(n, ty)| (n.clone(), self.to_type(ty)))
267 .collect(),
268 ret: method.ret.as_ref().map(|ty| self.to_type(ty)),
269 };
270 methods.push(func);
271 }
272 objs.push(AbiObject {
273 doc: object.doc.clone(),
274 name: object.ident.clone(),
275 methods,
276 destructor: format!("drop_box_{}", &object.ident),
277 });
278 }
279 objs
280 }
281
282 pub fn functions(&self) -> Vec<AbiFunction> {
283 let mut funcs = vec![];
284 for func in &self.functions {
285 assert!(!func.is_static);
286 let args = func
287 .args
288 .iter()
289 .map(|(n, ty)| (n.clone(), self.to_type(ty)))
290 .collect();
291 let ret = func.ret.as_ref().map(|ty| self.to_type(ty));
292 let func = AbiFunction {
293 doc: func.doc.clone(),
294 name: func.ident.clone(),
295 ty: FunctionType::Function,
296 args,
297 ret,
298 };
299 funcs.push(func);
300 }
301 funcs
302 }
303
304 pub fn iterators(&self) -> Vec<AbiIter> {
305 let mut iterators = vec![];
306 let mut functions = self.functions();
307 for obj in self.objects() {
308 functions.extend(obj.methods);
309 }
310 for func in functions {
311 if let Some(ty) = func.ret.as_ref() {
312 let mut p = ty;
313 let mut symbol = func.symbol();
314 loop {
315 match p {
316 AbiType::Option(ty) | AbiType::Result(ty) => p = &**ty,
317 AbiType::Future(ty) => {
318 symbol.push_str("_future_poll");
319 p = &**ty
320 }
321 AbiType::Stream(ty) => {
322 symbol.push_str("_stream_poll");
323 p = &**ty
324 }
325 AbiType::Iter(ty) => {
326 iterators.push(AbiIter {
327 ty: (&**ty).clone(),
328 symbol,
329 });
330 break;
331 }
332 _ => break,
333 }
334 }
335 }
336 }
337 iterators
338 }
339
340 pub fn futures(&self) -> Vec<AbiFuture> {
341 let mut futures = vec![];
342 let mut functions = self.functions();
343 for obj in self.objects() {
344 functions.extend(obj.methods);
345 }
346 for func in functions {
347 if let Some(ty) = func.ret.as_ref() {
348 let mut p = ty;
349 loop {
350 match p {
351 AbiType::Option(ty) | AbiType::Result(ty) => p = &**ty,
352 AbiType::Future(ty) => {
353 let symbol = func.symbol();
354 futures.push(AbiFuture {
355 ty: (&**ty).clone(),
356 symbol,
357 });
358 break;
359 }
360 _ => break,
361 }
362 }
363 }
364 }
365 futures
366 }
367
368 pub fn streams(&self) -> Vec<AbiStream> {
369 let mut streams = vec![];
370 let mut functions = self.functions();
371 for obj in self.objects() {
372 functions.extend(obj.methods);
373 }
374 for func in functions {
375 if let Some(ty) = func.ret.as_ref() {
376 let mut p = ty;
377 loop {
378 match p {
379 AbiType::Option(ty) | AbiType::Result(ty) => p = &**ty,
380 AbiType::Stream(ty) => {
381 let symbol = func.symbol();
382 streams.push(AbiStream {
383 ty: (&**ty).clone(),
384 symbol,
385 });
386 break;
387 }
388 _ => break,
389 }
390 }
391 }
392 }
393 streams
394 }
395
396 pub fn imports(&self, abi: &Abi) -> Vec<import::Import> {
397 let mut imports = vec![];
398 for function in self.functions() {
399 imports.push(abi.import(&function));
400 }
401 for obj in self.objects() {
402 for method in &obj.methods {
403 imports.push(abi.import(method));
404 }
405 }
406 for iter in self.iterators() {
407 imports.push(abi.import(&iter.next()));
408 }
409 for fut in self.futures() {
410 imports.push(abi.import(&fut.poll()));
411 }
412 for stream in self.streams() {
413 imports.push(abi.import(&stream.poll()));
414 }
415 imports
416 }
417
418 pub fn to_type(&self, ty: &Type) -> AbiType {
419 match ty {
420 Type::U8 => AbiType::Num(NumType::U8),
421 Type::U16 => AbiType::Num(NumType::U16),
422 Type::U32 => AbiType::Num(NumType::U32),
423 Type::U64 => AbiType::Num(NumType::U64),
424 Type::Usize => AbiType::Usize,
425 Type::I8 => AbiType::Num(NumType::I8),
426 Type::I16 => AbiType::Num(NumType::I16),
427 Type::I32 => AbiType::Num(NumType::I32),
428 Type::I64 => AbiType::Num(NumType::I64),
429 Type::Isize => AbiType::Isize,
430 Type::F32 => AbiType::Num(NumType::F32),
431 Type::F64 => AbiType::Num(NumType::F64),
432 Type::Bool => AbiType::Bool,
433 Type::Ref(inner) => match &**inner {
434 Type::String => AbiType::RefStr,
435 Type::Slice(inner) => match self.to_type(inner) {
436 AbiType::Num(ty) => AbiType::RefSlice(ty),
437 ty => unimplemented!("&{:?}", ty),
438 },
439 Type::Ident(ident) => {
440 if !self.is_object(ident) {
441 panic!("unknown identifier {}", ident);
442 }
443 AbiType::RefObject(ident.clone())
444 }
445 ty => unimplemented!("&{:?}", ty),
446 },
447 Type::String => AbiType::String,
448 Type::Slice(_) => panic!("slice needs to be passed by reference"),
449 Type::Vec(inner) => match self.to_type(inner) {
450 AbiType::Num(ty) => AbiType::Vec(ty),
451 ty => unimplemented!("Vec<{:?}>", ty),
452 },
453 Type::Ident(ident) => {
454 if !self.is_object(ident) {
455 panic!("unknown identifier {}", ident);
456 }
457 AbiType::Object(ident.clone())
458 }
459 Type::Option(ty) => {
460 let inner = self.to_type(ty);
461 if let AbiType::Option(_) = inner {
462 panic!("nested options are not supported");
463 }
464 AbiType::Option(Box::new(inner))
465 }
466 Type::Result(ty) => AbiType::Result(Box::new(self.to_type(ty))),
467 Type::Iter(ty) => AbiType::Iter(Box::new(self.to_type(ty))),
468 Type::Future(ty) => AbiType::Future(Box::new(self.to_type(ty))),
469 Type::Stream(ty) => AbiType::Stream(Box::new(self.to_type(ty))),
470 Type::Tuple(ty) => AbiType::Tuple(ty.iter().map(|ty| self.to_type(ty)).collect()),
471 }
472 }
473}