difftreelog
fix bindings argument layout
in: master
1 file changed
bindings/jsonnet/src/native.rsdiffbeforeafterboth1use std::{2 borrow::Cow,3 ffi::{c_void, CStr},4 os::raw::{c_char, c_int},5};67use jrsonnet_evaluator::{8 error::{Error, ErrorKind},9 function::builtin::{NativeCallback, NativeCallbackHandler},10 typed::Typed,11 IStr, Val,12};1314use crate::VM;1516/// The returned `JsonnetJsonValue*` should be allocated with `jsonnet_realloc`. It will be cleaned up17/// along with the objects rooted at `argv` by `libjsonnet` when no-longer needed. Return a string upon18/// failure, which will appear in Jsonnet as an error. The `argv` pointer is an array whose size19/// matches the array of parameters supplied when the native callback was originally registered.20///21/// - `ctx` User pointer, given in jsonnet_native_callback.22/// - `argv` Array of arguments from Jsonnet code.23/// - `param` success Set this byref param to 1 to indicate success and 0 for failure.24/// Returns the content of the imported file, or an error message.25type JsonnetNativeCallback = unsafe extern "C" fn(26 ctx: *const c_void,27 argv: *const *const Val,28 success: *mut c_int,29) -> *mut Val;3031#[derive(jrsonnet_gcmodule::Trace)]32struct JsonnetNativeCallbackHandler {33 #[trace(skip)]34 ctx: *const c_void,35 #[trace(skip)]36 cb: JsonnetNativeCallback,37}38impl NativeCallbackHandler for JsonnetNativeCallbackHandler {39 fn call(&self, args: &[Val]) -> Result<Val, Error> {40 let mut n_args = Vec::new();41 for a in args {42 n_args.push(Some(Box::new(a.clone())));43 }44 n_args.push(None);45 let mut success = 1;46 let v = unsafe {47 (self.cb)(48 self.ctx,49 &n_args as *const _ as *const *const Val,50 &mut success,51 )52 };53 let v = unsafe { *Box::from_raw(v) };54 if success == 1 {55 Ok(v)56 } else {57 let e = IStr::from_untyped(v).expect("error msg should be a string");58 Err(ErrorKind::RuntimeError(e).into())59 }60 }61}6263/// Callback to provide native extensions to Jsonnet.64///65/// # Safety66///67/// `vm` should be a vm allocated by `jsonnet_make`68/// `name` should be a NUL-terminated string69/// `cb` should be a function pointer70/// `raw_params` should point to a NULL-terminated array of NUL-terminated strings71#[no_mangle]72pub unsafe extern "C" fn jsonnet_native_callback(73 vm: &VM,74 name: *const c_char,75 cb: JsonnetNativeCallback,76 ctx: *const c_void,77 mut raw_params: *const *const c_char,78) {79 let name = CStr::from_ptr(name)80 .to_str()81 .expect("name is not utf-8")82 .into();83 let mut params = Vec::new();84 loop {85 if (*raw_params).is_null() {86 break;87 }88 let param = CStr::from_ptr(*raw_params)89 .to_str()90 .expect("param name is not utf-8");91 params.push(Cow::Owned(param.into()));92 raw_params = raw_params.offset(1);93 }9495 let any_resolver = vm.state.context_initializer();96 any_resolver97 .as_any()98 .downcast_ref::<jrsonnet_stdlib::ContextInitializer>()99 .expect("only stdlib context initializer supported")100 .add_native(101 name,102 #[allow(deprecated)]103 NativeCallback::new(params, JsonnetNativeCallbackHandler { ctx, cb }),104 )105}1use std::{2 borrow::Cow,3 ffi::{c_void, CStr},4 os::raw::{c_char, c_int},5};67use jrsonnet_evaluator::{8 error::{Error, ErrorKind},9 function::builtin::{NativeCallback, NativeCallbackHandler},10 typed::Typed,11 IStr, Val,12};1314use crate::VM;1516/// The returned `JsonnetJsonValue*` should be allocated with `jsonnet_realloc`. It will be cleaned up17/// along with the objects rooted at `argv` by `libjsonnet` when no-longer needed. Return a string upon18/// failure, which will appear in Jsonnet as an error. The `argv` pointer is an array whose size19/// matches the array of parameters supplied when the native callback was originally registered.20///21/// - `ctx` User pointer, given in jsonnet_native_callback.22/// - `argv` Array of arguments from Jsonnet code.23/// - `param` success Set this byref param to 1 to indicate success and 0 for failure.24/// Returns the content of the imported file, or an error message.25type JsonnetNativeCallback = unsafe extern "C" fn(26 ctx: *const c_void,27 argv: *const *const Val,28 success: *mut c_int,29) -> *mut Val;3031#[derive(jrsonnet_gcmodule::Trace)]32struct JsonnetNativeCallbackHandler {33 #[trace(skip)]34 ctx: *const c_void,35 #[trace(skip)]36 cb: JsonnetNativeCallback,37}38impl NativeCallbackHandler for JsonnetNativeCallbackHandler {39 fn call(&self, args: &[Val]) -> Result<Val, Error> {40 let mut n_args = Vec::new();41 for a in args {42 n_args.push(Some(Box::new(a.clone())));43 }44 n_args.push(None);45 let mut success = 1;46 let v = unsafe {47 (self.cb)(48 self.ctx,49 n_args.as_ptr().cast(),50 &mut success,51 )52 };53 let v = unsafe { *Box::from_raw(v) };54 if success == 1 {55 Ok(v)56 } else {57 let e = IStr::from_untyped(v).expect("error msg should be a string");58 Err(ErrorKind::RuntimeError(e).into())59 }60 }61}6263/// Callback to provide native extensions to Jsonnet.64///65/// # Safety66///67/// `vm` should be a vm allocated by `jsonnet_make`68/// `name` should be a NUL-terminated string69/// `cb` should be a function pointer70/// `raw_params` should point to a NULL-terminated array of NUL-terminated strings71#[no_mangle]72pub unsafe extern "C" fn jsonnet_native_callback(73 vm: &VM,74 name: *const c_char,75 cb: JsonnetNativeCallback,76 ctx: *const c_void,77 mut raw_params: *const *const c_char,78) {79 let name = CStr::from_ptr(name)80 .to_str()81 .expect("name is not utf-8")82 .into();83 let mut params = Vec::new();84 loop {85 if (*raw_params).is_null() {86 break;87 }88 let param = CStr::from_ptr(*raw_params)89 .to_str()90 .expect("param name is not utf-8");91 params.push(Cow::Owned(param.into()));92 raw_params = raw_params.offset(1);93 }9495 let any_resolver = vm.state.context_initializer();96 any_resolver97 .as_any()98 .downcast_ref::<jrsonnet_stdlib::ContextInitializer>()99 .expect("only stdlib context initializer supported")100 .add_native(101 name,102 #[allow(deprecated)]103 NativeCallback::new(params, JsonnetNativeCallbackHandler { ctx, cb }),104 )105}