Next Generation WASM Microkernel Operating System
wasm os rust microkernel
at trap_handler 138 lines 4.3 kB view raw
1use crate::core::*; 2use crate::kw; 3use crate::parser::{Parse, Parser, Result}; 4use crate::token::{Id, NameAnnotation, Span}; 5use alloc::boxed::Box; 6use alloc::vec::Vec; 7 8/// A WebAssembly function to be inserted into a module. 9/// 10/// This is a member of both the function and code sections. 11#[derive(Debug)] 12pub struct Func<'a> { 13 /// Where this `func` was defined. 14 pub span: Span, 15 /// An identifier that this function is resolved with (optionally) for name 16 /// resolution. 17 pub id: Option<Id<'a>>, 18 /// An optional name for this function stored in the custom `name` section. 19 pub name: Option<NameAnnotation<'a>>, 20 /// If present, inline export annotations which indicate names this 21 /// definition should be exported under. 22 pub exports: InlineExport<'a>, 23 /// What kind of function this is, be it an inline-defined or imported 24 /// function. 25 pub kind: FuncKind<'a>, 26 /// The type that this function will have. 27 pub ty: TypeUse<'a, FunctionType<'a>>, 28} 29 30/// Possible ways to define a function in the text format. 31#[derive(Debug)] 32pub enum FuncKind<'a> { 33 /// A function which is actually defined as an import, such as: 34 /// 35 /// ```text 36 /// (func (type 3) (import "foo" "bar")) 37 /// ``` 38 Import(InlineImport<'a>), 39 40 /// Almost all functions, those defined inline in a wasm module. 41 Inline { 42 /// The list of locals, if any, for this function. 43 locals: Box<[Local<'a>]>, 44 45 /// The instructions of the function. 46 expression: Expression<'a>, 47 }, 48} 49 50impl<'a> Parse<'a> for Func<'a> { 51 fn parse(parser: Parser<'a>) -> Result<Self> { 52 let span = parser.parse::<kw::func>()?.0; 53 let id = parser.parse()?; 54 let name = parser.parse()?; 55 let exports = parser.parse()?; 56 57 let (ty, kind) = if let Some(import) = parser.parse()? { 58 (parser.parse()?, FuncKind::Import(import)) 59 } else { 60 let ty = parser.parse()?; 61 let locals = Local::parse_remainder(parser)?.into(); 62 ( 63 ty, 64 FuncKind::Inline { 65 locals, 66 expression: parser.parse()?, 67 }, 68 ) 69 }; 70 71 Ok(Func { 72 span, 73 id, 74 name, 75 exports, 76 ty, 77 kind, 78 }) 79 } 80} 81 82/// A local for a `func` or `let` instruction. 83/// 84/// Each local has an optional identifier for name resolution, an optional name 85/// for the custom `name` section, and a value type. 86#[derive(Debug, Clone)] 87pub struct Local<'a> { 88 /// An identifier that this local is resolved with (optionally) for name 89 /// resolution. 90 pub id: Option<Id<'a>>, 91 /// An optional name for this local stored in the custom `name` section. 92 pub name: Option<NameAnnotation<'a>>, 93 /// The value type of this local. 94 pub ty: ValType<'a>, 95} 96 97/// Parser for `local` instruction. 98/// 99/// A single `local` instruction can generate multiple locals, hence this parser 100pub struct LocalParser<'a> { 101 /// All the locals associated with this `local` instruction. 102 pub locals: Vec<Local<'a>>, 103} 104 105impl<'a> Parse<'a> for LocalParser<'a> { 106 fn parse(parser: Parser<'a>) -> Result<Self> { 107 let mut locals = Vec::new(); 108 parser.parse::<kw::local>()?; 109 if !parser.is_empty() { 110 let id: Option<_> = parser.parse()?; 111 let name: Option<_> = parser.parse()?; 112 let ty = parser.parse()?; 113 let parse_more = id.is_none() && name.is_none(); 114 locals.push(Local { id, name, ty }); 115 while parse_more && !parser.is_empty() { 116 locals.push(Local { 117 id: None, 118 name: None, 119 ty: parser.parse()?, 120 }); 121 } 122 } 123 Ok(LocalParser { locals }) 124 } 125} 126 127impl<'a> Local<'a> { 128 pub(crate) fn parse_remainder(parser: Parser<'a>) -> Result<Vec<Local<'a>>> { 129 let mut locals = Vec::new(); 130 while parser.peek2::<kw::local>()? { 131 parser.parens(|p| { 132 locals.extend(p.parse::<LocalParser>()?.locals); 133 Ok(()) 134 })?; 135 } 136 Ok(locals) 137 } 138}