@@ -299,12 +299,12 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
299299 . get_file_mut ( u32:: from ( fd) ) ?
300300 . get_cap_mut ( FileCaps :: READ ) ?;
301301
302- let iovs: Vec < wiggle:: UnsafeGuestSlice < u8 > > = iovs
302+ let iovs: Vec < wiggle:: GuestPtr < [ u8 ] > > = iovs
303303 . iter ( )
304304 . map ( |iov_ptr| {
305305 let iov_ptr = iov_ptr?;
306306 let iov: types:: Iovec = iov_ptr. read ( ) ?;
307- Ok ( iov. buf . as_array ( iov. buf_len ) . as_unsafe_slice_mut ( ) ? )
307+ Ok ( iov. buf . as_array ( iov. buf_len ) )
308308 } )
309309 . collect :: < Result < _ , Error > > ( ) ?;
310310
@@ -326,24 +326,20 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
326326 . and_then ( |s| Some ( s. is_shared_memory ( ) ) )
327327 . unwrap_or ( false ) ;
328328 let bytes_read: u64 = if is_shared_memory {
329- // Read into an intermediate buffer.
330- let total_available_size = iovs. iter ( ) . fold ( 0 , |a, s| a + s. len ( ) ) ;
331- let mut buffer = vec ! [ 0 ; total_available_size. min( MAX_SHARED_BUFFER_SIZE ) ] ;
332- let bytes_read = f. read_vectored ( & mut [ IoSliceMut :: new ( & mut buffer) ] ) . await ?;
333-
334- // Copy the intermediate buffer into the Wasm shared memory--`iov`
335- // by `iov`.
336- let mut data_to_write = & buffer[ 0 ..] ;
337- for iov in iovs. into_iter ( ) {
338- let len = data_to_write. len ( ) . min ( iov. len ( ) ) ;
339- iov. copy_from_slice ( & data_to_write[ 0 ..len] ) ?;
340- data_to_write = & data_to_write[ len..] ;
341- if data_to_write. is_empty ( ) {
342- break ;
343- }
329+ // For shared memory, read into an intermediate buffer. Only the
330+ // first iov will be filled and even then the read is capped by the
331+ // `MAX_SHARED_BUFFER_SIZE`, so users are expected to re-call.
332+ let iov = iovs. into_iter ( ) . next ( ) ;
333+ if let Some ( iov) = iov {
334+ let mut buffer = vec ! [ 0 ; ( iov. len( ) as usize ) . min( MAX_SHARED_BUFFER_SIZE ) ] ;
335+ let bytes_read = f. read_vectored ( & mut [ IoSliceMut :: new ( & mut buffer) ] ) . await ?;
336+ iov. get_range ( 0 ..bytes_read. try_into ( ) ?)
337+ . expect ( "it should always be possible to slice the iov smaller" )
338+ . copy_from_slice ( & buffer[ 0 ..bytes_read. try_into ( ) ?] ) ?;
339+ bytes_read
340+ } else {
341+ return Ok ( 0 ) ;
344342 }
345-
346- bytes_read
347343 } else {
348344 // Convert all of the unsafe guest slices to safe ones--this uses
349345 // Wiggle's internal borrow checker to ensure no overlaps. We assume
@@ -376,12 +372,12 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
376372 . get_file_mut ( u32:: from ( fd) ) ?
377373 . get_cap_mut ( FileCaps :: READ | FileCaps :: SEEK ) ?;
378374
379- let iovs: Vec < wiggle:: UnsafeGuestSlice < u8 > > = iovs
375+ let iovs: Vec < wiggle:: GuestPtr < [ u8 ] > > = iovs
380376 . iter ( )
381377 . map ( |iov_ptr| {
382378 let iov_ptr = iov_ptr?;
383379 let iov: types:: Iovec = iov_ptr. read ( ) ?;
384- Ok ( iov. buf . as_array ( iov. buf_len ) . as_unsafe_slice_mut ( ) ? )
380+ Ok ( iov. buf . as_array ( iov. buf_len ) )
385381 } )
386382 . collect :: < Result < _ , Error > > ( ) ?;
387383
@@ -403,26 +399,22 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
403399 . and_then ( |s| Some ( s. is_shared_memory ( ) ) )
404400 . unwrap_or ( false ) ;
405401 let bytes_read: u64 = if is_shared_memory {
406- // Read into an intermediate buffer.
407- let total_available_size = iovs. iter ( ) . fold ( 0 , |a, s| a + s. len ( ) ) ;
408- let mut buffer = vec ! [ 0 ; total_available_size. min( MAX_SHARED_BUFFER_SIZE ) ] ;
409- let bytes_read = f
410- . read_vectored_at ( & mut [ IoSliceMut :: new ( & mut buffer) ] , offset)
411- . await ?;
412-
413- // Copy the intermediate buffer into the Wasm shared memory--`iov`
414- // by `iov`.
415- let mut data_to_write = & buffer[ 0 ..] ;
416- for iov in iovs. into_iter ( ) {
417- let len = data_to_write. len ( ) . min ( iov. len ( ) ) ;
418- iov. copy_from_slice ( & data_to_write[ 0 ..len] ) ?;
419- data_to_write = & data_to_write[ len..] ;
420- if data_to_write. is_empty ( ) {
421- break ;
422- }
402+ // For shared memory, read into an intermediate buffer. Only the
403+ // first iov will be filled and even then the read is capped by the
404+ // `MAX_SHARED_BUFFER_SIZE`, so users are expected to re-call.
405+ let iov = iovs. into_iter ( ) . next ( ) ;
406+ if let Some ( iov) = iov {
407+ let mut buffer = vec ! [ 0 ; ( iov. len( ) as usize ) . min( MAX_SHARED_BUFFER_SIZE ) ] ;
408+ let bytes_read = f
409+ . read_vectored_at ( & mut [ IoSliceMut :: new ( & mut buffer) ] , offset)
410+ . await ?;
411+ iov. get_range ( 0 ..bytes_read. try_into ( ) ?)
412+ . expect ( "it should always be possible to slice the iov smaller" )
413+ . copy_from_slice ( & buffer[ 0 ..bytes_read. try_into ( ) ?] ) ?;
414+ bytes_read
415+ } else {
416+ return Ok ( 0 ) ;
423417 }
424-
425- bytes_read
426418 } else {
427419 // Convert all of the unsafe guest slices to safe ones--this uses
428420 // Wiggle's internal borrow checker to ensure no overlaps. We assume
@@ -1169,12 +1161,12 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
11691161 . get_file_mut ( u32:: from ( fd) ) ?
11701162 . get_cap_mut ( FileCaps :: READ ) ?;
11711163
1172- let iovs: Vec < wiggle:: UnsafeGuestSlice < u8 > > = ri_data
1164+ let iovs: Vec < wiggle:: GuestPtr < [ u8 ] > > = ri_data
11731165 . iter ( )
11741166 . map ( |iov_ptr| {
11751167 let iov_ptr = iov_ptr?;
11761168 let iov: types:: Iovec = iov_ptr. read ( ) ?;
1177- Ok ( iov. buf . as_array ( iov. buf_len ) . as_unsafe_slice_mut ( ) ? )
1169+ Ok ( iov. buf . as_array ( iov. buf_len ) )
11781170 } )
11791171 . collect :: < Result < _ , Error > > ( ) ?;
11801172
@@ -1196,26 +1188,22 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
11961188 . and_then ( |s| Some ( s. is_shared_memory ( ) ) )
11971189 . unwrap_or ( false ) ;
11981190 let ( bytes_read, ro_flags) = if is_shared_memory {
1199- // Read into an intermediate buffer.
1200- let total_available_size = iovs. iter ( ) . fold ( 0 , |a, s| a + s. len ( ) ) ;
1201- let mut buffer = vec ! [ 0 ; total_available_size. min( MAX_SHARED_BUFFER_SIZE ) ] ;
1202- let ( bytes_read, ro_flags) = f
1203- . sock_recv ( & mut [ IoSliceMut :: new ( & mut buffer) ] , RiFlags :: from ( ri_flags) )
1204- . await ?;
1205-
1206- // Copy the intermediate buffer into the Wasm shared memory--`iov`
1207- // by `iov`.
1208- let mut data_to_write = & buffer[ 0 ..] ;
1209- for iov in iovs. into_iter ( ) {
1210- let len = data_to_write. len ( ) . min ( iov. len ( ) ) ;
1211- iov. copy_from_slice ( & data_to_write[ 0 ..len] ) ?;
1212- data_to_write = & data_to_write[ len..] ;
1213- if data_to_write. is_empty ( ) {
1214- break ;
1215- }
1191+ // For shared memory, read into an intermediate buffer. Only the
1192+ // first iov will be filled and even then the read is capped by the
1193+ // `MAX_SHARED_BUFFER_SIZE`, so users are expected to re-call.
1194+ let iov = iovs. into_iter ( ) . next ( ) ;
1195+ if let Some ( iov) = iov {
1196+ let mut buffer = vec ! [ 0 ; ( iov. len( ) as usize ) . min( MAX_SHARED_BUFFER_SIZE ) ] ;
1197+ let ( bytes_read, ro_flags) = f
1198+ . sock_recv ( & mut [ IoSliceMut :: new ( & mut buffer) ] , RiFlags :: from ( ri_flags) )
1199+ . await ?;
1200+ iov. get_range ( 0 ..bytes_read. try_into ( ) ?)
1201+ . expect ( "it should always be possible to slice the iov smaller" )
1202+ . copy_from_slice ( & buffer[ 0 ..bytes_read. try_into ( ) ?] ) ?;
1203+ ( bytes_read, ro_flags)
1204+ } else {
1205+ return Ok ( ( 0 , RoFlags :: empty ( ) . into ( ) ) ) ;
12161206 }
1217-
1218- ( bytes_read, ro_flags)
12191207 } else {
12201208 // Convert all of the unsafe guest slices to safe ones--this uses
12211209 // Wiggle's internal borrow checker to ensure no overlaps. We assume
0 commit comments