@@ -190,6 +190,32 @@ where
190
190
}
191
191
}
192
192
193
+ /// Represents a type-erased function provided by either the host or the WebAssembly program.
194
+ #[ allow( dead_code) ]
195
+ pub struct ErasedFunc < ' a > {
196
+ inner : Box < dyn Kind > ,
197
+
198
+ /// The function pointer.
199
+ func : NonNull < vm:: Func > ,
200
+
201
+ /// The function environment.
202
+ func_env : Option < NonNull < vm:: FuncEnv > > ,
203
+
204
+ /// The famous `vm::Ctx`.
205
+ vmctx : * mut vm:: Ctx ,
206
+
207
+ /// The runtime signature of this function.
208
+ ///
209
+ /// When converted from a `Func`, this is determined by the static `Args` and `Rets` type parameters.
210
+ /// otherwise the signature is dynamically assigned during `ErasedFunc` creation, usually when creating
211
+ /// a polymorphic host function.
212
+ signature : Arc < FuncSig > ,
213
+
214
+ _phantom : PhantomData < & ' a ( ) > ,
215
+ }
216
+
217
+ unsafe impl < ' a > Send for ErasedFunc < ' a > { }
218
+
193
219
/// Represents a function that can be used by WebAssembly.
194
220
pub struct Func < ' a , Args = ( ) , Rets = ( ) , Inner : Kind = Wasm > {
195
221
inner : Inner ,
@@ -203,17 +229,30 @@ pub struct Func<'a, Args = (), Rets = (), Inner: Kind = Wasm> {
203
229
/// The famous `vm::Ctx`.
204
230
vmctx : * mut vm:: Ctx ,
205
231
206
- /// The signature is usually infered from `Args` and `Rets`. In
207
- /// case of polymorphic function, the signature is only known at
208
- /// runtime.
209
- signature : Arc < FuncSig > ,
210
-
211
232
_phantom : PhantomData < ( & ' a ( ) , Args , Rets ) > ,
212
233
}
213
234
214
235
unsafe impl < ' a , Args , Rets > Send for Func < ' a , Args , Rets , Wasm > { }
215
236
unsafe impl < ' a , Args , Rets > Send for Func < ' a , Args , Rets , Host > { }
216
237
238
+ impl < ' a , Args , Rets , Inner > From < Func < ' a , Args , Rets , Inner > > for ErasedFunc < ' a >
239
+ where
240
+ Args : WasmTypeList ,
241
+ Rets : WasmTypeList ,
242
+ Inner : Kind + ' static ,
243
+ {
244
+ fn from ( that : Func < ' a , Args , Rets , Inner > ) -> ErasedFunc < ' a > {
245
+ ErasedFunc {
246
+ inner : Box :: new ( that. inner ) ,
247
+ func : that. func ,
248
+ func_env : that. func_env ,
249
+ vmctx : that. vmctx ,
250
+ signature : Arc :: new ( FuncSig :: new ( Args :: types ( ) , Rets :: types ( ) ) ) ,
251
+ _phantom : PhantomData ,
252
+ }
253
+ }
254
+ }
255
+
217
256
impl < ' a , Args , Rets > Func < ' a , Args , Rets , Wasm >
218
257
where
219
258
Args : WasmTypeList ,
@@ -230,7 +269,6 @@ where
230
269
func,
231
270
func_env,
232
271
vmctx,
233
- signature : Arc :: new ( FuncSig :: new ( Args :: types ( ) , Rets :: types ( ) ) ) ,
234
272
_phantom : PhantomData ,
235
273
}
236
274
}
@@ -254,13 +292,12 @@ where
254
292
func,
255
293
func_env,
256
294
vmctx : ptr:: null_mut ( ) ,
257
- signature : Arc :: new ( FuncSig :: new ( Args :: types ( ) , Rets :: types ( ) ) ) ,
258
295
_phantom : PhantomData ,
259
296
}
260
297
}
261
298
}
262
299
263
- impl < ' a > Func < ' a , ( ) , ( ) , Host > {
300
+ impl < ' a > ErasedFunc < ' a > {
264
301
/// Creates a polymorphic function.
265
302
#[ allow( unused_variables) ]
266
303
#[ cfg( all( unix, target_arch = "x86_64" ) ) ]
@@ -326,8 +363,8 @@ impl<'a> Func<'a, (), (), Host> {
326
363
. append_global ( )
327
364
. expect ( "cannot bump-allocate global trampoline memory" ) ;
328
365
329
- Func {
330
- inner : Host ( ( ) ) ,
366
+ ErasedFunc {
367
+ inner : Box :: new ( Host ( ( ) ) ) ,
331
368
func : ptr. cast :: < vm:: Func > ( ) ,
332
369
func_env : None ,
333
370
vmctx : ptr:: null_mut ( ) ,
@@ -765,6 +802,22 @@ impl_traits!([C] S24, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T
765
802
impl_traits ! ( [ C ] S25 , A , B , C , D , E , F , G , H , I , J , K , L , M , N , O , P , Q , R , S , T , U , V , W , X , Y ) ;
766
803
impl_traits ! ( [ C ] S26 , A , B , C , D , E , F , G , H , I , J , K , L , M , N , O , P , Q , R , S , T , U , V , W , X , Y , Z ) ;
767
804
805
+ impl < ' a > IsExport for ErasedFunc < ' a > {
806
+ fn to_export ( & self ) -> Export {
807
+ let func = unsafe { FuncPointer :: new ( self . func . as_ptr ( ) ) } ;
808
+ let ctx = match self . func_env {
809
+ func_env @ Some ( _) => Context :: ExternalWithEnv ( self . vmctx , func_env) ,
810
+ None => Context :: Internal ,
811
+ } ;
812
+
813
+ Export :: Function {
814
+ func,
815
+ ctx,
816
+ signature : self . signature . clone ( ) ,
817
+ }
818
+ }
819
+ }
820
+
768
821
impl < ' a , Args , Rets , Inner > IsExport for Func < ' a , Args , Rets , Inner >
769
822
where
770
823
Args : WasmTypeList ,
@@ -781,7 +834,7 @@ where
781
834
Export :: Function {
782
835
func,
783
836
ctx,
784
- signature : self . signature . clone ( ) ,
837
+ signature : Arc :: new ( FuncSig :: new ( Args :: types ( ) , Rets :: types ( ) ) ) ,
785
838
}
786
839
}
787
840
}
0 commit comments