123use 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 35 #[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 41 42 43 #[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 101 102 103 104 105 106 107 108 109 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 128 ctx.interner = null_mut();129 ctx.gc = null_mut();130 }131132 133 134 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}