git.delta.rocks / jrsonnet / refs/commits / 2c370b494610

difftreelog

source

bindings/jsonnet/src/native.rs1.9 KiBsourcehistory
1use std::{2	ffi::{c_void, CStr},3	os::raw::{c_char, c_int},4	path::Path,5	rc::Rc,6};78use gcmodule::Cc;9use jrsonnet_evaluator::{10	error::{Error, LocError},11	function::BuiltinParam,12	gc::TraceBox,13	native::{NativeCallback, NativeCallbackHandler},14	typed::Typed,15	IStr, State, Val,16};1718type JsonnetNativeCallback = unsafe extern "C" fn(19	ctx: *const c_void,20	argv: *const *const Val,21	success: *mut c_int,22) -> *mut Val;2324#[derive(gcmodule::Trace)]25struct JsonnetNativeCallbackHandler {26	#[skip_trace]27	ctx: *const c_void,28	#[skip_trace]29	cb: JsonnetNativeCallback,30}31impl NativeCallbackHandler for JsonnetNativeCallbackHandler {32	fn call(&self, s: State, _from: Option<Rc<Path>>, args: &[Val]) -> Result<Val, LocError> {33		let mut n_args = Vec::new();34		for a in args {35			n_args.push(Some(Box::new(a.clone())));36		}37		n_args.push(None);38		let mut success = 1;39		let v = unsafe {40			(self.cb)(41				self.ctx,42				&n_args as *const _ as *const *const Val,43				&mut success,44			)45		};46		let v = unsafe { *Box::from_raw(v) };47		if success == 1 {48			Ok(v)49		} else {50			let e = IStr::from_untyped(v, s).expect("error msg");51			Err(Error::RuntimeError(e).into())52		}53	}54}5556/// # Safety57#[no_mangle]58pub unsafe extern "C" fn jsonnet_native_callback(59	vm: &State,60	name: *const c_char,61	cb: JsonnetNativeCallback,62	ctx: *const c_void,63	mut raw_params: *const *const c_char,64) {65	let name = CStr::from_ptr(name).to_str().expect("utf8 name").into();66	let mut params = Vec::new();67	loop {68		if (*raw_params).is_null() {69			break;70		}71		let param = CStr::from_ptr(*raw_params).to_str().expect("not utf8");72		params.push(BuiltinParam {73			name: param.into(),74			has_default: false,75		});76		raw_params = raw_params.offset(1);77	}7879	vm.add_native(80		name,81		#[allow(deprecated)]82		Cc::new(TraceBox(Box::new(NativeCallback::new(83			params,84			TraceBox(Box::new(JsonnetNativeCallbackHandler { ctx, cb })),85		)))),86	)87}