message: rust: add Instance and instantiate
diff: @@ -34,6 +34,44 @@ pub fn parse<T: AsRef<[u8]>>(input: &T) -> Result<Module, ()> {
  Ok(Module { 0: ptr })
  }
  +/// An instance of a module.
  +pub struct Instance(NonNull<sys::FizzyInstance>);
  +
  +impl Drop for Instance {
  + fn drop(&mut self) {
  + unsafe { sys::fizzy_free_instance(self.0.as_ptr()) }
  + }
  +}
  +
  +impl Module {
  + /// Create an instance of a module.
  + // TODO: support imported functions
  + pub fn instantiate(self) -> Result<Instance, ()> {
  + if self.0.is_null() {
  + return Err(());
  + }
  + let ptr = unsafe {
  + sys::fizzy_instantiate(
  + self.0,
  + std::ptr::null(),
  + 0,
  + std::ptr::null(),
  + std::ptr::null(),
  + std::ptr::null(),
  + 0,
  + )
  + };
  + // Forget Module (and avoid calling drop) because it has been consumed by instantiate (even if it failed).
  + core::mem::forget(self);
  + if ptr.is_null() {
  + return Err(());
  + }
  + Ok(Instance {
  + 0: unsafe { NonNull::new_unchecked(ptr) },
  + })
  + }
  +}
  +
  #[cfg(test)]
  mod tests {
  use super::*;
  @@ -61,4 +99,12 @@ mod tests {
  assert!(parse(&[0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00]).is_ok());
  assert!(parse(&[0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x01]).is_err());
  }
  +
  + #[test]
  + fn instantiate_wasm() {
  + let module = parse(&[0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00]);
  + assert!(module.is_ok());
  + let instance = module.unwrap().instantiate();
  + assert!(instance.is_ok());
  + }
  }
  