TheButlah commented on issue #273:
URL: 
https://github.com/apache/teaclave-trustzone-sdk/issues/273#issuecomment-3866067134

   I'm not sure anymore that using the `volatile` crate is the right choice. 
Most of the apis require unstable compiler intrinsics. Here's the general 
approach I think we should take instead:
   * ParamMemref has a generic `A` (meaning "Access"), with traits and zst 
structs like this:
   
   ```rust
   mod private {
       pub trait Sealed{}
   }
   
   mod access {
       pub struct Read;
       pub struct Write;
       pub struct ReadWrite;
   
       pub trait Access: private::Sealed {}
       pub trait Readable: Access {}
       pub trait Writable: Access {}
   
       impl private::Sealed for Read {}
       impl private::Sealed for Write {}
       impl private::Sealed for ReadWrite {}
   
       impl Access for Read {}
       impl Access for Write {}
       impl Access for ReadWrite {}
   
       impl Readable for Read {}
       impl Readable for ReadWrite {}
   
       impl Writeable for Write {}
       impl Writeable for ReadWrite {}
   }
   ```
   
   calling `.as_memref()` results in a `ParamMemref<'parameter, ()>` which 
exposes no reading or writing functionality, only basic c-style access like 
getting the raw pointer, the size, etc.
   
   To be able to read to the buffer, we call `.in()` or `.inout()` (or maybe 
`.access::<Read>()` or `.access::<ReadWrite>()`) (or maybe .as_ which returns a 
`Result<ParamMemref<'parameter, Read>, InvalidAccessErr>`
   
   Then, we can implement things like 
   
   ```rust
   impl <'parameter, A> ParamMemref<'parameter, A> {
       pub fn buffer(&mut self) -> VolatileBuf<'parameter, A> {  /* ... */ }
   
   
   
       /// The size of the allocated memory region (i.e. the original value of 
`self.size`
       pub fn capacity(&self) -> usize { /* ... */ }
   }
   
   impl <'parameter, A: access::Writeable> ParamMemref<'parameter, A> {
       /// Essentially the same as the old set_update_size function, but now 
with a check that it doesn't exceed capacity.
       pub fn set_updated_size(&mut self, length: usize) -> Result<(), 
BiggerThanCapacityErr> { /* ... */ }
   }
   ```
   
   Finally the volatile types would be like this:
   
   ```
   pub struct VolatileBuf<'parameter, A> {
       _phantom: PhantomData<&'parameter ()>,
       ptr: *mut u8,
       capacity: usize,
   }
   
   impl <'parameter, A: access::Readable> VolatileBuf<'parameter, A> {
       //// Returns `WouldOverflowErr` if the output buffer is smaller than 
`self.capacity()`.
       pub fn copy_to(&self, out: &mut [u8]) -> Result<(), WouldOverflowErr> { 
/* ... */ }
   
       //// Reads the value at the given index. Returns an error if `index >= 
self.capacity()`.
       pub fn read(&self, index: usize) -> Result<u8, OutOfBoundsErr> { /* ... 
*/ }
   }
   
   impl <'parameter, A: access::Writeable> VolatileBuf<'parameter, A> {
       /// Copies all values from `values` into `self`. Returns 
`WouldOverflowErr` if the copy would exceed the capacity of `self`.
       pub fn copy_from(&mut self, values: &[u8]) -> Result<(), 
WouldOverflowErr> { /* ... */ }
   
       /// Writes to a location in the buffer. Returns an error if `index >= 
self.capacity()`.
       pub fn write(&mut self, index: usize) -> Result<(), OutOfBoundsErr> { /* 
... */ }
   }
   ```


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to