@@ -209,7 +209,9 @@ impl ExecutionEngine {
209
209
/// The `Symbol` wrapper ensures a function won't accidentally outlive the
210
210
/// execution engine it came from, but adding functions after calling this
211
211
/// method *may* invalidate the function pointer.
212
- pub unsafe fn get_function < F > ( & self , fn_name : & str ) -> Result < Symbol < F > , FunctionLookupError > {
212
+ pub unsafe fn get_function < F > ( & self , fn_name : & str ) -> Result < Symbol < F > , FunctionLookupError >
213
+ where F : UnsafeFunctionPointer
214
+ {
213
215
if !self . jit_mode {
214
216
return Err ( FunctionLookupError :: JITNotEnabled ) ;
215
217
}
@@ -294,19 +296,48 @@ impl ExecutionEngine {
294
296
/// A wrapper around a function pointer which ensures the symbol being pointed
295
297
/// to doesn't accidentally outlive its execution engine.
296
298
#[ derive( Debug , Clone ) ]
297
- pub struct Symbol < F > {
299
+ pub struct Symbol < F : UnsafeFunctionPointer > {
298
300
pub ( crate ) execution_engine : Rc < LLVMExecutionEngineRef > ,
299
301
inner : F ,
300
302
}
301
303
302
- impl < F > Deref for Symbol < F > {
304
+ impl < F : UnsafeFunctionPointer > Deref for Symbol < F > {
303
305
type Target = F ;
304
306
305
307
fn deref ( & self ) -> & Self :: Target {
306
308
& self . inner
307
309
}
308
310
}
309
311
312
+ /// Marker trait representing an unsafe function pointer (`unsafe extern "C" fn(A, B, ...) -> Output`).
313
+ pub trait UnsafeFunctionPointer : private:: Sealed { }
314
+
315
+ mod private {
316
+ /// A sealed trait which ensures nobody outside this crate can implement
317
+ /// `UnsafeFunctionPointer`.
318
+ ///
319
+ /// See https://rust-lang-nursery.github.io/api-guidelines/future-proofing.html
320
+ pub trait Sealed { }
321
+ }
322
+
323
+ macro_rules! impl_unsafe_fn {
324
+ ( $( $param: ident ) ,* ) => {
325
+ impl <Output , $( $param ) ,* > private:: Sealed for unsafe extern "C" fn ( $( $param ) ,* ) -> Output { }
326
+ impl <Output , $( $param ) ,* > UnsafeFunctionPointer for unsafe extern "C" fn ( $( $param ) ,* ) -> Output { }
327
+ } ;
328
+ }
329
+
330
+ impl_unsafe_fn ! ( ) ;
331
+ impl_unsafe_fn ! ( A ) ;
332
+ impl_unsafe_fn ! ( A , B ) ;
333
+ impl_unsafe_fn ! ( A , B , C ) ;
334
+ impl_unsafe_fn ! ( A , B , C , D ) ;
335
+ impl_unsafe_fn ! ( A , B , C , D , E ) ;
336
+ impl_unsafe_fn ! ( A , B , C , D , E , F ) ;
337
+ impl_unsafe_fn ! ( A , B , C , D , E , F , G ) ;
338
+ impl_unsafe_fn ! ( A , B , C , D , E , F , G , H ) ;
339
+ impl_unsafe_fn ! ( A , B , C , D , E , F , G , H , I ) ;
340
+
310
341
// Modules owned by the EE will be discarded by the EE so we don't
311
342
// want owned modules to drop.
312
343
impl Drop for ExecutionEngine {
0 commit comments