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

difftreelog

source

bindings/jsonnet/src/interop.rs4.0 KiBsourcehistory
1//! Jrsonnet specific additional binding helpers23use crate::VM;45#[cfg(feature = "interop-wasm")]6pub mod wasm {7	use std::ffi::{c_char, c_int, c_void};89	use jrsonnet_evaluator::Val;1011	use crate::VM;1213	extern "C" {1415		pub fn _jrsonnet_static_import_callback(16			ctx: *mut c_void,17			base: *const c_char,18			rel: *const c_char,19			found_here: *mut *const c_char,20			buf: *mut *mut c_char,21			buflen: *mut usize,22		) -> c_int;2324		#[allow(improper_ctypes)]25		pub fn _jrsonnet_static_native_callback(26			ctx: *const c_void,27			argv: *const *const Val,28			success: *mut c_int,29		) -> *mut Val;30	}3132	#[no_mangle]33	#[cfg(feature = "interop-wasm")]34	// ctx arg is passed as-is to callback35	#[allow(clippy::not_unsafe_ptr_arg_deref)]36	pub extern "C" fn jrsonnet_apply_static_import_callback(vm: &VM, ctx: *mut c_void) {37		unsafe { crate::import::jsonnet_import_callback(vm, _jrsonnet_static_import_callback, ctx) }38	}3940	/// # Safety41	///42	/// `name` and `raw_params` should be correctly initialized43	#[no_mangle]44	#[cfg(feature = "interop-wasm")]45	pub unsafe extern "C" fn jrsonnet_apply_static_native_callback(46		vm: &VM,47		name: *const c_char,48		ctx: *mut c_void,49		raw_params: *const *const c_char,50	) {51		unsafe {52			crate::native::jsonnet_native_callback(53				vm,54				name,55				_jrsonnet_static_native_callback,56				ctx,57				raw_params,58			);59		}60	}61}6263#[cfg(feature = "interop-common")]64mod common {65	use jrsonnet_evaluator::trace::{CompactFormat, ExplainingFormat, JsFormat, PathResolver};6667	use crate::VM;6869	#[no_mangle]70	pub extern "C" fn jrsonnet_set_trace_format(vm: &mut VM, format: u8) {71		match format {72			0 => {73				vm.trace_format = Box::new(CompactFormat {74					max_trace: 20,75					resolver: PathResolver::new_cwd_fallback(),76					padding: 4,77				});78			}79			1 => vm.trace_format = Box::new(JsFormat { max_trace: 20 }),80			2 => {81				vm.trace_format = Box::new(ExplainingFormat {82					resolver: PathResolver::new_cwd_fallback(),83					max_trace: 20,84				});85			}86			_ => panic!("unknown trace format"),87		}88	}89}9091#[cfg(feature = "interop-threading")]92mod threading {93	use std::{ffi::c_int, thread::ThreadId};9495	pub struct ThreadCTX {96		interner: *mut jrsonnet_interner::interop::PoolState,97		gc: *mut jrsonnet_gcmodule::interop::GcState,98	}99100	/// Golang jrsonnet bindings require Jsonnet VM to be movable.101	/// Jrsonnet uses `thread_local` in some places, thus making VM102	/// immovable by default. By using `jrsonnet_exit_thread` and103	/// `jrsonnet_reenter_thread`, you can move `thread_local` state to104	/// where it is more convinient to use it.105	///106	/// # Safety107	///108	/// Current thread GC will be broken after this call, need to call109	/// `jrsonet_enter_thread` before doing anything.110	#[no_mangle]111	pub unsafe extern "C" fn jrsonnet_exit_thread() -> *mut ThreadCTX {112		Box::into_raw(Box::new(ThreadCTX {113			interner: jrsonnet_interner::interop::exit_thread(),114			gc: unsafe { jrsonnet_gcmodule::interop::exit_thread() },115		}))116	}117118	#[no_mangle]119	pub extern "C" fn jrsonnet_reenter_thread(mut ctx: Box<ThreadCTX>) {120		use std::ptr::null_mut;121		assert!(122			!ctx.interner.is_null() && !ctx.gc.is_null(),123			"reused context?"124		);125		unsafe { jrsonnet_interner::interop::reenter_thread(ctx.interner) }126		unsafe { jrsonnet_gcmodule::interop::reenter_thread(ctx.gc) }127		// Just in case128		ctx.interner = null_mut();129		ctx.gc = null_mut();130	}131132	// ThreadId is compatible with u64, and there is unstable cast133	// method... But until it is stabilized, lets erase its type by134	// boxing.135	pub enum JrThreadId {}136137	#[no_mangle]138	pub extern "C" fn jrsonnet_thread_id() -> *mut JrThreadId {139		Box::into_raw(Box::new(std::thread::current().id())).cast()140	}141142	#[no_mangle]143	pub extern "C" fn jrsonnet_thread_id_compare(144		a: *const JrThreadId,145		b: *const JrThreadId,146	) -> c_int {147		let a: &ThreadId = unsafe { *a.cast() };148		let b: &ThreadId = unsafe { *b.cast() };149		i32::from(*a == *b)150	}151152	#[no_mangle]153	pub unsafe extern "C" fn jrsonnet_thread_id_free(id: *mut JrThreadId) {154		let _id: Box<ThreadId> = unsafe { Box::from_raw(id.cast()) };155	}156}