1pub mod import;2pub mod interop;3pub mod native;4pub mod val_extract;5pub mod val_make;6pub mod val_modify;7pub mod vars_tlas;89use import::NativeImportResolver;10use jrsonnet_evaluator::{EvaluationState, ManifestFormat, Val};11use jrsonnet_interner::IStr;12use std::{13 alloc::Layout,14 ffi::{CStr, CString},15 os::raw::{c_char, c_double, c_int, c_uint},16 path::PathBuf,17 rc::Rc,18};192021#[cfg(target_arch = "wasm32")]22#[no_mangle]23pub extern "C" fn _start() {}2425#[no_mangle]26pub extern "C" fn jsonnet_version() -> &'static [u8; 8] {27 b"v0.16.0\0"28}2930#[no_mangle]31pub extern "C" fn jsonnet_make() -> *mut EvaluationState {32 let state = EvaluationState::default();33 state.with_stdlib();34 state.settings_mut().import_resolver = Box::new(NativeImportResolver::default());35 Box::into_raw(Box::new(state))36}373839#[no_mangle]40#[allow(clippy::boxed_local)]41pub unsafe extern "C" fn jsonnet_destroy(vm: *mut EvaluationState) {42 Box::from_raw(vm);43}4445#[no_mangle]46pub extern "C" fn jsonnet_max_stack(vm: &EvaluationState, v: c_uint) {47 vm.settings_mut().max_stack = v as usize;48}495051#[no_mangle]52pub extern "C" fn jsonnet_gc_min_objects(_vm: &EvaluationState, _v: c_uint) {}53#[no_mangle]54pub extern "C" fn jsonnet_gc_growth_trigger(_vm: &EvaluationState, _v: c_double) {}5556#[no_mangle]57pub extern "C" fn jsonnet_string_output(vm: &EvaluationState, v: c_int) {58 match v {59 1 => vm.set_manifest_format(ManifestFormat::String),60 0 => vm.set_manifest_format(ManifestFormat::Json(4)),61 _ => panic!("incorrect output format"),62 }63}6465666768#[no_mangle]69pub unsafe extern "C" fn jsonnet_realloc(70 _vm: &EvaluationState,71 buf: *mut u8,72 sz: usize,73) -> *mut u8 {74 if buf.is_null() {75 assert!(sz != 0);76 return std::alloc::alloc(Layout::from_size_align(sz, std::mem::align_of::<u8>()).unwrap());77 }78 79 80 81 82 let old_layout = Layout::from_size_align(16, std::mem::align_of::<u8>()).unwrap();83 if sz == 0 {84 std::alloc::dealloc(buf, old_layout);85 return std::ptr::null_mut();86 }87 std::alloc::realloc(buf, old_layout, sz)88}899091#[no_mangle]92#[allow(clippy::boxed_local)]93pub unsafe extern "C" fn jsonnet_json_destroy(_vm: &EvaluationState, v: *mut Val) {94 Box::from_raw(v);95}9697#[no_mangle]98pub extern "C" fn jsonnet_max_trace(vm: &EvaluationState, v: c_uint) {99 vm.set_max_trace(v as usize)100}101102103104105#[no_mangle]106pub unsafe extern "C" fn jsonnet_evaluate_file(107 vm: &EvaluationState,108 filename: *const c_char,109 error: &mut c_int,110) -> *const c_char {111 vm.run_in_state(|| {112 let filename = CStr::from_ptr(filename);113 match vm114 .evaluate_file_raw_nocwd(&PathBuf::from(filename.to_str().unwrap()))115 .and_then(|v| vm.with_tla(v))116 .and_then(|v| vm.manifest(v))117 {118 Ok(v) => {119 *error = 0;120 CString::new(&*v as &str).unwrap().into_raw()121 }122 Err(e) => {123 *error = 1;124 let out = vm.stringify_err(&e);125 CString::new(&out as &str).unwrap().into_raw()126 }127 }128 })129}130131132133134#[no_mangle]135pub unsafe extern "C" fn jsonnet_evaluate_snippet(136 vm: &EvaluationState,137 filename: *const c_char,138 snippet: *const c_char,139 error: &mut c_int,140) -> *const c_char {141 vm.run_in_state(|| {142 let filename = CStr::from_ptr(filename);143 let snippet = CStr::from_ptr(snippet);144 match vm145 .evaluate_snippet_raw(146 Rc::new(PathBuf::from(filename.to_str().unwrap())),147 snippet.to_str().unwrap().into(),148 )149 .and_then(|v| vm.with_tla(v))150 .and_then(|v| vm.manifest(v))151 {152 Ok(v) => {153 *error = 0;154 CString::new(&*v as &str).unwrap().into_raw()155 }156 Err(e) => {157 *error = 1;158 let out = vm.stringify_err(&e);159 CString::new(&out as &str).unwrap().into_raw()160 }161 }162 })163}164165fn multi_to_raw(multi: Vec<(IStr, IStr)>) -> *const c_char {166 let mut out = Vec::new();167 for (i, (k, v)) in multi.iter().enumerate() {168 if i != 0 {169 out.push(0);170 }171 out.extend_from_slice(k.as_bytes());172 out.push(0);173 out.extend_from_slice(v.as_bytes());174 }175 out.push(0);176 out.push(0);177 let v = out.as_ptr();178 std::mem::forget(out);179 v as *const c_char180}181182183#[no_mangle]184pub unsafe extern "C" fn jsonnet_evaluate_file_multi(185 vm: &EvaluationState,186 filename: *const c_char,187 error: &mut c_int,188) -> *const c_char {189 vm.run_in_state(|| {190 let filename = CStr::from_ptr(filename);191 match vm192 .evaluate_file_raw_nocwd(&PathBuf::from(filename.to_str().unwrap()))193 .and_then(|v| vm.with_tla(v))194 .and_then(|v| vm.manifest_multi(v))195 {196 Ok(v) => {197 *error = 0;198 multi_to_raw(v)199 }200 Err(e) => {201 *error = 1;202 let out = vm.stringify_err(&e);203 CString::new(&out as &str).unwrap().into_raw()204 }205 }206 })207}208209210#[no_mangle]211pub unsafe extern "C" fn jsonnet_evaluate_snippet_multi(212 vm: &EvaluationState,213 filename: *const c_char,214 snippet: *const c_char,215 error: &mut c_int,216) -> *const c_char {217 vm.run_in_state(|| {218 let filename = CStr::from_ptr(filename);219 let snippet = CStr::from_ptr(snippet);220 match vm221 .evaluate_snippet_raw(222 Rc::new(PathBuf::from(filename.to_str().unwrap())),223 snippet.to_str().unwrap().into(),224 )225 .and_then(|v| vm.with_tla(v))226 .and_then(|v| vm.manifest_multi(v))227 {228 Ok(v) => {229 *error = 0;230 multi_to_raw(v)231 }232 Err(e) => {233 *error = 1;234 let out = vm.stringify_err(&e);235 CString::new(&out as &str).unwrap().into_raw()236 }237 }238 })239}240241fn stream_to_raw(multi: Vec<IStr>) -> *const c_char {242 let mut out = Vec::new();243 for (i, v) in multi.iter().enumerate() {244 if i != 0 {245 out.push(0);246 }247 out.extend_from_slice(v.as_bytes());248 }249 out.push(0);250 out.push(0);251 let v = out.as_ptr();252 std::mem::forget(out);253 v as *const c_char254}255256257#[no_mangle]258pub unsafe extern "C" fn jsonnet_evaluate_file_stream(259 vm: &EvaluationState,260 filename: *const c_char,261 error: &mut c_int,262) -> *const c_char {263 vm.run_in_state(|| {264 let filename = CStr::from_ptr(filename);265 match vm266 .evaluate_file_raw_nocwd(&PathBuf::from(filename.to_str().unwrap()))267 .and_then(|v| vm.with_tla(v))268 .and_then(|v| vm.manifest_stream(v))269 {270 Ok(v) => {271 *error = 0;272 stream_to_raw(v)273 }274 Err(e) => {275 *error = 1;276 let out = vm.stringify_err(&e);277 CString::new(&out as &str).unwrap().into_raw()278 }279 }280 })281}282283284#[no_mangle]285pub unsafe extern "C" fn jsonnet_evaluate_snippet_stream(286 vm: &EvaluationState,287 filename: *const c_char,288 snippet: *const c_char,289 error: &mut c_int,290) -> *const c_char {291 vm.run_in_state(|| {292 let filename = CStr::from_ptr(filename);293 let snippet = CStr::from_ptr(snippet);294 match vm295 .evaluate_snippet_raw(296 Rc::new(PathBuf::from(filename.to_str().unwrap())),297 snippet.to_str().unwrap().into(),298 )299 .and_then(|v| vm.with_tla(v))300 .and_then(|v| vm.manifest_stream(v))301 {302 Ok(v) => {303 *error = 0;304 stream_to_raw(v)305 }306 Err(e) => {307 *error = 1;308 let out = vm.stringify_err(&e);309 CString::new(&out as &str).unwrap().into_raw()310 }311 }312 })313}