git.delta.rocks / jrsonnet / refs/commits / c137fa77fb64

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::builtin::{BuiltinParam, NativeCallback, NativeCallbackHandler},12	gc::TraceBox,13	typed::Typed,14	IStr, State, Val,15};1617type JsonnetNativeCallback = unsafe extern "C" fn(18	ctx: *const c_void,19	argv: *const *const Val,20	success: *mut c_int,21) -> *mut Val;2223#[derive(gcmodule::Trace)]24struct JsonnetNativeCallbackHandler {25	#[skip_trace]26	ctx: *const c_void,27	#[skip_trace]28	cb: JsonnetNativeCallback,29}30impl NativeCallbackHandler for JsonnetNativeCallbackHandler {31	fn call(&self, s: State, _from: Option<Rc<Path>>, args: &[Val]) -> Result<Val, LocError> {32		let mut n_args = Vec::new();33		for a in args {34			n_args.push(Some(Box::new(a.clone())));35		}36		n_args.push(None);37		let mut success = 1;38		let v = unsafe {39			(self.cb)(40				self.ctx,41				&n_args as *const _ as *const *const Val,42				&mut success,43			)44		};45		let v = unsafe { *Box::from_raw(v) };46		if success == 1 {47			Ok(v)48		} else {49			let e = IStr::from_untyped(v, s).expect("error msg");50			Err(Error::RuntimeError(e).into())51		}52	}53}5455/// # Safety56#[no_mangle]57pub unsafe extern "C" fn jsonnet_native_callback(58	vm: &State,59	name: *const c_char,60	cb: JsonnetNativeCallback,61	ctx: *const c_void,62	mut raw_params: *const *const c_char,63) {64	let name = CStr::from_ptr(name).to_str().expect("utf8 name").into();65	let mut params = Vec::new();66	loop {67		if (*raw_params).is_null() {68			break;69		}70		let param = CStr::from_ptr(*raw_params).to_str().expect("not utf8");71		params.push(BuiltinParam {72			name: param.into(),73			has_default: false,74		});75		raw_params = raw_params.offset(1);76	}7778	vm.add_native(79		name,80		#[allow(deprecated)]81		Cc::new(TraceBox(Box::new(NativeCallback::new(82			params,83			TraceBox(Box::new(JsonnetNativeCallbackHandler { ctx, cb })),84		)))),85	)86}