@@ -30,13 +30,15 @@ impl<'a> ReturnedData<'a> {
30
30
31
31
impl Drop for ReturnedData < ' _ > {
32
32
fn drop ( & mut self ) {
33
- self . free_function
34
- . call (
35
- & mut * self . context_mut ,
36
- & [ Value :: I32 ( self . ptr as _ ) , Value :: I32 ( self . len as _ ) ] ,
37
- & mut [ ] ,
38
- )
39
- . unwrap ( ) ;
33
+ if self . ptr != 0 {
34
+ self . free_function
35
+ . call (
36
+ & mut * self . context_mut ,
37
+ & [ Value :: I32 ( self . ptr as _ ) , Value :: I32 ( self . len as _ ) ] ,
38
+ & mut [ ] ,
39
+ )
40
+ . unwrap ( ) ;
41
+ }
40
42
}
41
43
}
42
44
@@ -123,36 +125,40 @@ impl PluginInstance {
123
125
} )
124
126
}
125
127
126
- fn write ( & mut self , args : & [ & [ u8 ] ] ) {
127
- self . store . data_mut ( ) . arg_buffer = args. concat ( ) ;
128
- }
129
-
130
- pub fn call ( & mut self , function : & str , args : & [ & [ u8 ] ] ) -> Result < ReturnedData , String > {
131
- self . write ( args) ;
128
+ pub fn call < ' a > (
129
+ & mut self ,
130
+ function : & str ,
131
+ args : impl IntoIterator < Item = & ' a [ u8 ] > ,
132
+ ) -> Result < ReturnedData , String > {
133
+ self . store . data_mut ( ) . result_ptr = 0 ;
134
+ self . store . data_mut ( ) . result_len = 0 ;
135
+
136
+ let mut result_args = Vec :: new ( ) ;
137
+ let arg_buffer = & mut self . store . data_mut ( ) . arg_buffer ;
138
+ arg_buffer. clear ( ) ;
139
+ for arg in args {
140
+ result_args. push ( Value :: I32 ( arg. len ( ) as _ ) ) ;
141
+ arg_buffer. extend_from_slice ( arg) ;
142
+ }
132
143
133
144
let ( _, function) = self
134
145
. functions
135
146
. iter ( )
136
147
. find ( |( s, _) | s == function)
137
- . ok_or ( format ! ( "Plugin doesn't have the method: {function}" ) ) ?;
138
-
139
- let result_args = args
140
- . iter ( )
141
- . map ( |a| Value :: I32 ( a. len ( ) as _ ) )
142
- . collect :: < Vec < _ > > ( ) ;
148
+ . ok_or ( format ! ( "plugin doesn't have the method: {function}" ) ) ?;
143
149
144
- let mut code = [ Value :: I32 ( 2 ) ] ;
145
- let is_err = function
146
- . call ( & mut self . store , & result_args, & mut code)
147
- . is_err ( ) ;
148
- let code = if is_err {
149
- Value :: I32 ( 2 )
150
- } else {
151
- code. first ( ) . cloned ( ) . unwrap_or ( Value :: I32 ( 3 ) ) // if the function returns nothing
152
- } ;
150
+ let mut code = Value :: I32 ( 2 ) ;
151
+ let ty = function. ty ( & self . store ) ;
152
+ if ty. params ( ) . len ( ) != result_args. len ( ) {
153
+ return Err ( "incorrect number of arguments" . to_string ( ) ) ;
154
+ }
153
155
156
+ let call_result = function. call (
157
+ & mut self . store ,
158
+ & result_args,
159
+ std:: array:: from_mut ( & mut code) ,
160
+ ) ;
154
161
let ( ptr, len) = ( self . store . data ( ) . result_ptr , self . store . data ( ) . result_len ) ;
155
-
156
162
let result = ReturnedData {
157
163
memory : self . memory ,
158
164
ptr,
@@ -161,13 +167,18 @@ impl PluginInstance {
161
167
context_mut : & mut self . store ,
162
168
} ;
163
169
170
+ match call_result {
171
+ Ok ( ( ) ) => { }
172
+ Err ( wasmi:: Error :: Trap ( _) ) => return Err ( "plugin panicked" . to_string ( ) ) ,
173
+ Err ( _) => return Err ( "plugin did not respect the protocol" . to_string ( ) ) ,
174
+ } ;
175
+
164
176
match code {
165
177
Value :: I32 ( 0 ) => Ok ( result) ,
166
178
Value :: I32 ( 1 ) => Err ( match std:: str:: from_utf8 ( result. get ( ) ) {
167
179
Ok ( err) => format ! ( "plugin errored with: '{}'" , err, ) ,
168
180
Err ( _) => String :: from ( "plugin errored and did not return valid UTF-8" ) ,
169
181
} ) ,
170
- Value :: I32 ( 2 ) => Err ( "plugin panicked" . to_string ( ) ) ,
171
182
_ => Err ( "plugin did not respect the protocol" . to_string ( ) ) ,
172
183
}
173
184
}
0 commit comments