git.delta.rocks / jrsonnet / refs/heads / master

difftreelog

source

bindings/jsonnet/src/interop.rs2.7 KiBsourcehistory
1//! Jrsonnet specific additional binding helpers23#[cfg(feature = "interop-common")]4mod common {5	use jrsonnet_evaluator::trace::{CompactFormat, HiDocFormat, JsFormat, PathResolver};67	use crate::VM;89	#[unsafe(no_mangle)]10	pub extern "C" fn jrsonnet_set_trace_format(vm: &mut VM, format: u8) {11		match format {12			0 => {13				vm.trace_format = Box::new(CompactFormat {14					max_trace: 20,15					resolver: PathResolver::new_cwd_fallback(),16					padding: 4,17				});18			}19			1 => vm.trace_format = Box::new(JsFormat { max_trace: 20 }),20			2 => {21				vm.trace_format = Box::new(HiDocFormat {22					resolver: PathResolver::new_cwd_fallback(),23					max_trace: 20,24				});25			}26			_ => panic!("unknown trace format"),27		}28	}29}3031#[cfg(feature = "interop-threading")]32mod threading {33	use std::{ffi::c_int, thread::ThreadId};3435	pub struct ThreadCTX {36		interner: *mut jrsonnet_interner::interop::PoolState,37		gc: *mut jrsonnet_gcmodule::interop::GcState,38	}3940	/// Golang jrsonnet bindings require Jsonnet VM to be movable.41	/// Jrsonnet uses `thread_local` in some places, thus making VM42	/// immovable by default. By using `jrsonnet_exit_thread` and43	/// `jrsonnet_reenter_thread`, you can move `thread_local` state to44	/// where it is more convinient to use it.45	///46	/// # Safety47	///48	/// Current thread GC will be broken after this call, need to call49	/// `jrsonet_enter_thread` before doing anything.50	#[unsafe(no_mangle)]51	pub unsafe extern "C" fn jrsonnet_exit_thread() -> *mut ThreadCTX {52		Box::into_raw(Box::new(ThreadCTX {53			interner: jrsonnet_interner::interop::exit_thread(),54			gc: unsafe { jrsonnet_gcmodule::interop::exit_thread() },55		}))56	}5758	#[unsafe(no_mangle)]59	pub extern "C" fn jrsonnet_reenter_thread(mut ctx: Box<ThreadCTX>) {60		use std::ptr::null_mut;61		assert!(62			!ctx.interner.is_null() && !ctx.gc.is_null(),63			"reused context?"64		);65		unsafe { jrsonnet_interner::interop::reenter_thread(ctx.interner) }66		unsafe { jrsonnet_gcmodule::interop::reenter_thread(ctx.gc) }67		// Just in case68		ctx.interner = null_mut();69		ctx.gc = null_mut();70	}7172	// ThreadId is compatible with u64, and there is unstable cast73	// method... But until it is stabilized, lets erase its type by74	// boxing.75	pub enum JrThreadId {}7677	#[unsafe(no_mangle)]78	pub extern "C" fn jrsonnet_thread_id() -> *mut JrThreadId {79		Box::into_raw(Box::new(std::thread::current().id())).cast()80	}8182	#[unsafe(no_mangle)]83	pub extern "C" fn jrsonnet_thread_id_compare(84		a: *const JrThreadId,85		b: *const JrThreadId,86	) -> c_int {87		let a: &ThreadId = unsafe { *a.cast() };88		let b: &ThreadId = unsafe { *b.cast() };89		i32::from(*a == *b)90	}9192	#[unsafe(no_mangle)]93	pub unsafe extern "C" fn jrsonnet_thread_id_free(id: *mut JrThreadId) {94		let _id: Box<ThreadId> = unsafe { Box::from_raw(id.cast()) };95	}96}