123#[cfg(feature = "interop-wasm")]4pub mod wasm {5 use std::ffi::{c_char, c_int, c_void};67 use jrsonnet_evaluator::Val;89 use crate::VM;1011 extern "C" {1213 pub fn _jrsonnet_static_import_callback(14 ctx: *mut c_void,15 base: *const c_char,16 rel: *const c_char,17 found_here: *mut *const c_char,18 buf: *mut *mut c_char,19 buflen: *mut usize,20 ) -> c_int;2122 #[allow(improper_ctypes)]23 pub fn _jrsonnet_static_native_callback(24 ctx: *const c_void,25 argv: *const *const Val,26 success: *mut c_int,27 ) -> *mut Val;28 }2930 #[no_mangle]31 #[cfg(feature = "interop-wasm")]32 33 #[allow(clippy::not_unsafe_ptr_arg_deref)]34 pub extern "C" fn jrsonnet_apply_static_import_callback(vm: &VM, ctx: *mut c_void) {35 unsafe { crate::import::jsonnet_import_callback(vm, _jrsonnet_static_import_callback, ctx) }36 }3738 39 40 41 #[no_mangle]42 #[cfg(feature = "interop-wasm")]43 pub unsafe extern "C" fn jrsonnet_apply_static_native_callback(44 vm: &VM,45 name: *const c_char,46 ctx: *mut c_void,47 raw_params: *const *const c_char,48 ) {49 unsafe {50 crate::native::jsonnet_native_callback(51 vm,52 name,53 _jrsonnet_static_native_callback,54 ctx,55 raw_params,56 );57 }58 }59}6061#[cfg(feature = "interop-common")]62mod common {63 use jrsonnet_evaluator::trace::{CompactFormat, HiDocFormat, JsFormat, PathResolver};6465 use crate::VM;6667 #[no_mangle]68 pub extern "C" fn jrsonnet_set_trace_format(vm: &mut VM, format: u8) {69 match format {70 0 => {71 vm.trace_format = Box::new(CompactFormat {72 max_trace: 20,73 resolver: PathResolver::new_cwd_fallback(),74 padding: 4,75 });76 }77 1 => vm.trace_format = Box::new(JsFormat { max_trace: 20 }),78 2 => {79 vm.trace_format = Box::new(HiDocFormat {80 resolver: PathResolver::new_cwd_fallback(),81 max_trace: 20,82 });83 }84 _ => panic!("unknown trace format"),85 }86 }87}8889#[cfg(feature = "interop-threading")]90mod threading {91 use std::{ffi::c_int, thread::ThreadId};9293 pub struct ThreadCTX {94 interner: *mut jrsonnet_interner::interop::PoolState,95 gc: *mut jrsonnet_gcmodule::interop::GcState,96 }9798 99 100 101 102 103 104 105 106 107 108 #[no_mangle]109 pub unsafe extern "C" fn jrsonnet_exit_thread() -> *mut ThreadCTX {110 Box::into_raw(Box::new(ThreadCTX {111 interner: jrsonnet_interner::interop::exit_thread(),112 gc: unsafe { jrsonnet_gcmodule::interop::exit_thread() },113 }))114 }115116 #[no_mangle]117 pub extern "C" fn jrsonnet_reenter_thread(mut ctx: Box<ThreadCTX>) {118 use std::ptr::null_mut;119 assert!(120 !ctx.interner.is_null() && !ctx.gc.is_null(),121 "reused context?"122 );123 unsafe { jrsonnet_interner::interop::reenter_thread(ctx.interner) }124 unsafe { jrsonnet_gcmodule::interop::reenter_thread(ctx.gc) }125 126 ctx.interner = null_mut();127 ctx.gc = null_mut();128 }129130 131 132 133 pub enum JrThreadId {}134135 #[no_mangle]136 pub extern "C" fn jrsonnet_thread_id() -> *mut JrThreadId {137 Box::into_raw(Box::new(std::thread::current().id())).cast()138 }139140 #[no_mangle]141 pub extern "C" fn jrsonnet_thread_id_compare(142 a: *const JrThreadId,143 b: *const JrThreadId,144 ) -> c_int {145 let a: &ThreadId = unsafe { *a.cast() };146 let b: &ThreadId = unsafe { *b.cast() };147 i32::from(*a == *b)148 }149150 #[no_mangle]151 pub unsafe extern "C" fn jrsonnet_thread_id_free(id: *mut JrThreadId) {152 let _id: Box<ThreadId> = unsafe { Box::from_raw(id.cast()) };153 }154}