1- use jrsonnet_evaluator:: { error:: Error , native:: NativeCallback , EvaluationState , Val } ;
1+ use jrsonnet_evaluator:: {
2+ error:: { Error , LocError } ,
3+ native:: { NativeCallback , NativeCallbackHandler } ,
4+ EvaluationState , Val ,
5+ } ;
6+ use jrsonnet_gc:: { unsafe_empty_trace, Finalize , Gc , Trace } ;
27use jrsonnet_parser:: { Param , ParamsDesc } ;
38use std:: {
49 ffi:: { c_void, CStr } ,
510 os:: raw:: { c_char, c_int} ,
11+ path:: Path ,
612 rc:: Rc ,
713} ;
814
@@ -12,6 +18,39 @@ type JsonnetNativeCallback = unsafe extern "C" fn(
1218 success : * mut c_int ,
1319) -> * mut Val ;
1420
21+ struct JsonnetNativeCallbackHandler {
22+ ctx : * const c_void ,
23+ cb : JsonnetNativeCallback ,
24+ }
25+ impl Finalize for JsonnetNativeCallbackHandler { }
26+ unsafe impl Trace for JsonnetNativeCallbackHandler {
27+ unsafe_empty_trace ! ( ) ;
28+ }
29+ impl NativeCallbackHandler for JsonnetNativeCallbackHandler {
30+ fn call ( & self , _from : Option < Rc < Path > > , args : & [ Val ] ) -> Result < Val , LocError > {
31+ let mut n_args = Vec :: new ( ) ;
32+ for a in args {
33+ n_args. push ( Some ( Box :: new ( a. clone ( ) ) ) ) ;
34+ }
35+ n_args. push ( None ) ;
36+ let mut success = 1 ;
37+ let v = unsafe {
38+ ( self . cb ) (
39+ self . ctx ,
40+ & n_args as * const _ as * const * const Val ,
41+ & mut success,
42+ )
43+ } ;
44+ let v = unsafe { * Box :: from_raw ( v) } ;
45+ if success == 1 {
46+ Ok ( v)
47+ } else {
48+ let e = v. try_cast_str ( "native error" ) . expect ( "error msg" ) ;
49+ Err ( Error :: RuntimeError ( e) . into ( ) )
50+ }
51+ }
52+ }
53+
1554/// # Safety
1655#[ no_mangle]
1756pub unsafe extern "C" fn jsonnet_native_callback (
@@ -35,21 +74,9 @@ pub unsafe extern "C" fn jsonnet_native_callback(
3574
3675 vm. add_native (
3776 name,
38- Rc :: new ( NativeCallback :: new ( params, move |_caller, args| {
39- let mut n_args = Vec :: new ( ) ;
40- for a in args {
41- n_args. push ( Some ( Box :: new ( a. clone ( ) ) ) ) ;
42- }
43- n_args. push ( None ) ;
44- let mut success = 1 ;
45- let v = cb ( ctx, & n_args as * const _ as * const * const Val , & mut success) ;
46- let v = * Box :: from_raw ( v) ;
47- if success == 1 {
48- Ok ( v)
49- } else {
50- let e = v. try_cast_str ( "native error" ) . expect ( "error msg" ) ;
51- Err ( Error :: RuntimeError ( e) . into ( ) )
52- }
53- } ) ) ,
77+ Gc :: new ( NativeCallback :: new (
78+ params,
79+ Box :: new ( JsonnetNativeCallbackHandler { ctx, cb } ) ,
80+ ) ) ,
5481 )
5582}
0 commit comments