Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion phases/ephemeral/witx/typenames.witx
Original file line number Diff line number Diff line change
Expand Up @@ -281,8 +281,9 @@
)
)

(resource $fd)
;;; A file descriptor handle.
(typename $fd (handle))
(typename $fd (handle $fd))

;;; A region of memory for scatter/gather reads.
(typename $iovec
Expand Down
3 changes: 2 additions & 1 deletion phases/old/snapshot_0/witx/typenames.witx
Original file line number Diff line number Diff line change
Expand Up @@ -273,8 +273,9 @@
)
)

(resource $fd)
;;; A file descriptor handle.
(typename $fd (handle))
(typename $fd (handle $fd))

;;; A region of memory for scatter/gather reads.
(typename $iovec
Expand Down
3 changes: 2 additions & 1 deletion phases/snapshot/witx/typenames.witx
Original file line number Diff line number Diff line change
Expand Up @@ -273,8 +273,9 @@
)
)

(resource $fd)
;;; A file descriptor handle.
(typename $fd (handle))
(typename $fd (handle $fd))

;;; A region of memory for scatter/gather reads.
(typename $iovec
Expand Down
53 changes: 50 additions & 3 deletions tools/witx/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ pub struct Module {
types: Vec<Rc<NamedType>>,
type_map: HashMap<Id, Rc<NamedType>>,

resources: Vec<Rc<Resource>>,
resource_map: HashMap<Id, Rc<Resource>>,

funcs: Vec<Rc<Function>>,
func_map: HashMap<Id, Rc<Function>>,

Expand All @@ -61,6 +64,8 @@ impl Module {
module_id,
types: Default::default(),
type_map: Default::default(),
resources: Default::default(),
resource_map: Default::default(),
funcs: Default::default(),
func_map: Default::default(),
constants: Default::default(),
Expand All @@ -80,6 +85,14 @@ impl Module {
self.types.push(ty);
}

pub(crate) fn push_resource(&mut self, r: Rc<Resource>) {
assert!(self
.resource_map
.insert(r.name.clone(), r.clone())
.is_none());
self.resources.push(r);
}

pub(crate) fn push_func(&mut self, func: Rc<Function>) {
assert!(self
.func_map
Expand All @@ -100,6 +113,14 @@ impl Module {
self.types.iter()
}

pub fn resource(&self, name: &Id) -> Option<Rc<Resource>> {
self.resource_map.get(name).cloned()
}

pub fn resources<'a>(&'a self) -> impl Iterator<Item = &'a Rc<Resource>> + 'a {
self.resources.iter()
}

/// All of the (unique) types used as "err" variant of results returned from
/// functions.
pub fn error_types<'a>(&'a self) -> impl Iterator<Item = TypeRef> + 'a {
Expand Down Expand Up @@ -499,11 +520,37 @@ impl Case {
}

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct HandleDatatype {}
pub struct Resource {
/// The local name within the module this resource is defined within. This
/// may differ from the id of the resource itself.
pub name: Id,
/// The unique id assigned to this resource.
pub resource_id: ResourceId,
/// Documentation in the defining module, if any.
pub docs: String,
}

/// A unique id used to determine whether two handles are nominally referring
/// to the same resource.
///
/// An id is composed of the definition location (a module id) and the original
/// name within that module.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ResourceId {
pub name: Id,
pub module_id: ModuleId,
}

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct HandleDatatype {
/// The resource that this handle references, used for determining if two
/// handle types are nominally equal to one another.
pub resource_id: ResourceId,
}

impl HandleDatatype {
pub fn type_equal(&self, _other: &HandleDatatype) -> bool {
true
pub fn type_equal(&self, other: &HandleDatatype) -> bool {
self.resource_id == other.resource_id
}
}

Expand Down
58 changes: 53 additions & 5 deletions tools/witx/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,13 @@ mod kw {
wast::custom_keyword!(noreturn);
wast::custom_keyword!(pointer);
wast::custom_keyword!(record);
wast::custom_keyword!(r#as = "as");
wast::custom_keyword!(r#const = "const");
wast::custom_keyword!(r#enum = "enum");
wast::custom_keyword!(r#union = "union");
wast::custom_keyword!(r#use = "use");
wast::custom_keyword!(repr);
wast::custom_keyword!(resource);
wast::custom_keyword!(s16);
wast::custom_keyword!(s32);
wast::custom_keyword!(s64);
Expand Down Expand Up @@ -227,6 +229,7 @@ impl<'a> Parse<'a> for TopLevelModule<'a> {
if parser.peek2::<kw::r#use>()
|| parser.peek2::<annotation::witx>()
|| parser.peek2::<kw::typename>()
|| parser.peek2::<kw::resource>()
{
decls.push(Documented {
comments,
Expand Down Expand Up @@ -279,6 +282,7 @@ impl<'a> Parse<'a> for TopLevelSyntax<'a> {
#[derive(Debug, Clone)]
pub enum DeclSyntax<'a> {
Typename(TypenameSyntax<'a>),
Resource(ResourceSyntax<'a>),
Const(Documented<'a, ConstSyntax<'a>>),
}

Expand All @@ -289,6 +293,8 @@ impl<'a> Parse<'a> for DeclSyntax<'a> {
Ok(DeclSyntax::Typename(parser.parse()?))
} else if l.peek::<annotation::witx>() {
Ok(DeclSyntax::Const(parser.parse()?))
} else if l.peek::<kw::resource>() {
Ok(DeclSyntax::Resource(parser.parse()?))
} else {
Err(l.error())
}
Expand All @@ -313,7 +319,7 @@ impl<'a> Parse<'a> for UseSyntax<'a> {

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum UsedNames<'a> {
List(Vec<wast::Id<'a>>),
List(Vec<UseName<'a>>),
All(wast::Span),
}

Expand All @@ -333,6 +339,32 @@ impl<'a> Parse<'a> for UsedNames<'a> {
}
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct UseName<'a> {
pub other_name: wast::Id<'a>,
pub our_name: wast::Id<'a>,
}

impl<'a> Parse<'a> for UseName<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
let (other_name, our_name) = if parser.peek::<wast::Id>() {
let name = parser.parse()?;
(name, name)
} else {
parser.parens(|p| {
let other_name = p.parse()?;
p.parse::<kw::r#as>()?;
let our_name = p.parse()?;
Ok((other_name, our_name))
})?
};
Ok(UseName {
other_name,
our_name,
})
}
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TypenameSyntax<'a> {
pub ident: wast::Id<'a>,
Expand All @@ -357,7 +389,7 @@ pub enum TypedefSyntax<'a> {
Record(RecordSyntax<'a>),
Union(UnionSyntax<'a>),
Variant(VariantSyntax<'a>),
Handle(HandleSyntax),
Handle(HandleSyntax<'a>),
List(Box<TypedefSyntax<'a>>),
Pointer(Box<TypedefSyntax<'a>>),
ConstPointer(Box<TypedefSyntax<'a>>),
Expand Down Expand Up @@ -521,6 +553,19 @@ impl<'a> Parse<'a> for ConstSyntax<'a> {
}
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ResourceSyntax<'a> {
pub ident: wast::Id<'a>,
}

impl<'a> Parse<'a> for ResourceSyntax<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::resource>()?;
let ident = parser.parse()?;
Ok(ResourceSyntax { ident })
}
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct FlagsSyntax<'a> {
pub repr: Option<BuiltinType>,
Expand Down Expand Up @@ -656,12 +701,15 @@ impl<'a> Parse<'a> for CaseSyntax<'a> {
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct HandleSyntax {}
pub struct HandleSyntax<'a> {
pub resource: wast::Id<'a>,
}

impl<'a> Parse<'a> for HandleSyntax {
impl<'a> Parse<'a> for HandleSyntax<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::handle>()?;
Ok(HandleSyntax {})
let resource = parser.parse()?;
Ok(HandleSyntax { resource })
}
}

Expand Down
15 changes: 0 additions & 15 deletions tools/witx/src/toplevel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,19 +165,4 @@ mod test {
e => panic!("wrong error: {:?}", e),
}
}

#[test]
fn use_invalid() {
match parse_witx_with("/a", &MockFs::new(&[("/a", "(use bbbbbbb)")]))
.err()
.unwrap()
{
WitxError::Parse(e) => {
let err = e.to_string();
assert!(err.contains("expected an identifier"), "bad error: {}", err);
assert!(err.contains("/a:1:6"));
}
e => panic!("wrong error: {:?}", e),
}
}
}
Loading