11use alloc:: collections:: VecDeque ;
22use alloc:: vec:: Vec ;
3+ use core:: future;
34use core:: hint:: black_box;
45use core:: mem:: MaybeUninit ;
6+ use core:: task:: Poll ;
57
68use hermit_sync:: InterruptTicketMutex ;
79use wasi:: * ;
810use wasmtime:: * ;
911use zerocopy:: IntoBytes ;
1012
11- use crate :: fd;
13+ use crate :: console:: CONSOLE ;
14+ use crate :: executor:: { WakerRegistration , spawn} ;
1215use crate :: kernel:: systemtime:: now_micros;
1316
1417mod capi;
@@ -42,6 +45,26 @@ pub(crate) static WASM_MANAGER: InterruptTicketMutex<Option<WasmManager>> =
4245 InterruptTicketMutex :: new ( None ) ;
4346pub ( crate ) static INPUT : InterruptTicketMutex < VecDeque < Vec < u8 > > > =
4447 InterruptTicketMutex :: new ( VecDeque :: new ( ) ) ;
48+ static OUTPUT : InterruptTicketMutex < WasmStdout > = InterruptTicketMutex :: new ( WasmStdout :: new ( ) ) ;
49+
50+ struct WasmStdout {
51+ pub data : VecDeque < Vec < u8 > > ,
52+ pub waker : WakerRegistration ,
53+ }
54+
55+ impl WasmStdout {
56+ pub const fn new ( ) -> Self {
57+ Self {
58+ data : VecDeque :: new ( ) ,
59+ waker : WakerRegistration :: new ( ) ,
60+ }
61+ }
62+
63+ pub fn write ( & mut self , buf : & [ u8 ] ) {
64+ self . data . push_back ( buf. to_vec ( ) ) ;
65+ self . waker . wake ( ) ;
66+ }
67+ }
4568
4669pub ( crate ) struct WasmManager {
4770 store : Store < u32 > ,
@@ -79,7 +102,6 @@ impl WasmManager {
79102 panic ! ( "fd_read: invalid file descriptor {}" , fd) ;
80103 } ;
81104
82- info ! ( "fd {}" , fd) ;
83105 if let Some ( Extern :: Memory ( mem) ) = caller. get_export ( "memory" ) {
84106 let mut iovs = vec ! [ 0i32 ; ( 2 * iovs_len) . try_into( ) . unwrap( ) ] ;
85107 let _ = mem. read (
@@ -89,21 +111,18 @@ impl WasmManager {
89111 ) ;
90112
91113 let mut nread_bytes: i32 = 0 ;
92- let mut i = 0 ;
114+ let i = 0 ;
93115 if let Some ( data) = INPUT . lock ( ) . pop_front ( ) {
94- let len = iovs[ i + 1 ] ;
95- info ! ( "len = {}, {}" , len, data. len( ) ) ;
116+ let _len = iovs[ i + 1 ] ;
96117
97- while i < iovs . len ( ) {
118+ if !data . is_empty ( ) {
98119 let _ = mem. write (
99120 caller. as_context_mut ( ) ,
100121 iovs[ i] . try_into ( ) . unwrap ( ) ,
101122 & data,
102123 ) ;
103124
104125 nread_bytes += data. len ( ) as i32 ;
105-
106- i += 2 ;
107126 }
108127 }
109128
@@ -125,16 +144,10 @@ impl WasmManager {
125144 "wasi_snapshot_preview1" ,
126145 "fd_write" ,
127146 |mut caller : Caller < ' _ , u32 > ,
128- fd : i32 ,
147+ _fd : i32 ,
129148 iovs_ptr : i32 ,
130149 iovs_len : i32 ,
131150 nwritten_ptr : i32 | {
132- let fd = if fd <= 2 {
133- fd
134- } else {
135- panic ! ( "fd_write: invalid file descriptor {}" , fd) ;
136- } ;
137-
138151 if let Some ( Extern :: Memory ( mem) ) = caller. get_export ( "memory" ) {
139152 let mut iovs = vec ! [ 0i32 ; ( 2 * iovs_len) . try_into( ) . unwrap( ) ] ;
140153 let _ = mem. read (
@@ -165,14 +178,8 @@ impl WasmManager {
165178 iovs[ i] . try_into ( ) . unwrap ( ) ,
166179 unsafe { data. assume_init_mut ( ) } ,
167180 ) ;
168- let result = fd:: write ( fd, unsafe { data. assume_init_ref ( ) } ) ;
169-
170- match result {
171- Ok ( n) => {
172- nwritten_bytes += n as i32 ;
173- }
174- Err ( err) => return -i32:: from ( err) ,
175- }
181+ OUTPUT . lock ( ) . write ( unsafe { data. assume_init_mut ( ) } ) ;
182+ nwritten_bytes += len;
176183
177184 i += 2 ;
178185 }
@@ -263,6 +270,18 @@ pub extern "C" fn sys_unload_binary() -> i32 {
263270 0
264271}
265272
273+ async fn wasm_run ( ) {
274+ future:: poll_fn ( |cx| {
275+ let mut guard = OUTPUT . lock ( ) ;
276+ while let Some ( data) = guard. data . pop_front ( ) {
277+ CONSOLE . lock ( ) . write ( & data) ;
278+ }
279+ guard. waker . register ( cx. waker ( ) ) ;
280+ Poll :: < ( ) > :: Pending
281+ } )
282+ . await ;
283+ }
284+
266285#[ hermit_macro:: system]
267286#[ unsafe( no_mangle) ]
268287pub extern "C" fn sys_load_binary ( ptr : * const u8 , len : usize ) -> i32 {
@@ -277,6 +296,8 @@ pub extern "C" fn sys_load_binary(ptr: *const u8, len: usize) -> i32 {
277296 let _ = wasm_manager. call_func :: < ( ) , ( ) > ( "hello_world" , ( ) ) ;
278297 }
279298
299+ spawn ( wasm_run ( ) ) ;
300+
280301 0
281302}
282303
0 commit comments