git.delta.rocks / jrsonnet / refs/commits / 020afa68e92f

difftreelog

feat native callbacks

Lach2020-08-23parent: #1feb056.patch.diff
in: master

10 files changed

modifiedbindings/jsonnet/src/interop.rsdiffbeforeafterboth
1//! Jrsonnet specific additional binding helpers1//! Jrsonnet specific additional binding helpers
22
3use crate::import::jsonnet_import_callback;3use crate::{import::jsonnet_import_callback, native::jsonnet_native_callback};
4use jrsonnet_evaluator::EvaluationState;4use jrsonnet_evaluator::{EvaluationState, Val};
5use std::{5use std::{
6 ffi::c_void,6 ffi::c_void,
7 os::raw::{c_char, c_int},7 os::raw::{c_char, c_int},
16 success: &mut c_int,16 success: &mut c_int,
17 ) -> *const c_char;17 ) -> *const c_char;
18
19 #[allow(improper_ctypes)]
20 pub fn _jrsonnet_static_native_callback(
21 ctx: *const c_void,
22 argv: *const *const Val,
23 success: *mut c_int,
24 ) -> *mut Val;
18}25}
1926
20/// # Safety27/// # Safety
26 jsonnet_import_callback(vm, _jrsonnet_static_import_callback, ctx)33 jsonnet_import_callback(vm, _jrsonnet_static_import_callback, ctx)
27}34}
35
36/// # Safety
37#[no_mangle]
38pub unsafe extern "C" fn jrsonnet_apply_static_native_callback(
39 vm: &EvaluationState,
40 name: *const c_char,
41 ctx: *mut c_void,
42 raw_params: *const *const c_char,
43) {
44 jsonnet_native_callback(vm, name, _jrsonnet_static_native_callback, ctx, raw_params)
45}
2846
29#[no_mangle]47#[no_mangle]
30pub extern "C" fn jrsonnet_set_trace_format(vm: &EvaluationState, format: u8) {48pub extern "C" fn jrsonnet_set_trace_format(vm: &EvaluationState, format: u8) {
modifiedbindings/jsonnet/src/lib.rsdiffbeforeafterboth
1pub mod import;1pub mod import;
2pub mod interop;2pub mod interop;
3pub mod native;
3pub mod val_extract;4pub mod val_extract;
4pub mod val_make;5pub mod val_make;
5pub mod val_modify;6pub mod val_modify;
92 Box::from_raw(v);93 Box::from_raw(v);
93}94}
94
95#[no_mangle]
96pub extern "C" fn jsonnet_native_callback() {
97 todo!()
98}
9995
100#[no_mangle]96#[no_mangle]
101pub extern "C" fn jsonnet_max_trace(vm: &EvaluationState, v: c_uint) {97pub extern "C" fn jsonnet_max_trace(vm: &EvaluationState, v: c_uint) {
addedbindings/jsonnet/src/native.rsdiffbeforeafterboth

no changes

modifiedcrates/jrsonnet-evaluator/src/builtin/manifest.rsdiffbeforeafterboth
117 }117 }
118 buf.push('}');118 buf.push('}');
119 }119 }
120 Val::Func(_) | Val::Intristic(_, _) => {120 Val::Func(_) | Val::Intristic(_, _) | Val::NativeExt(_, _) => {
121 throw!(RuntimeError("tried to manifest function".into()))121 throw!(RuntimeError("tried to manifest function".into()))
122 }122 }
123 Val::Lazy(_) => unreachable!(),123 Val::Lazy(_) => unreachable!(),
modifiedcrates/jrsonnet-evaluator/src/error.rsdiffbeforeafterboth
33 FunctionParameterNotBoundInCall(Rc<str>),33 FunctionParameterNotBoundInCall(Rc<str>),
3434
35 UndefinedExternalVariable(Rc<str>),35 UndefinedExternalVariable(Rc<str>),
36 UndefinedExternalFunction(Rc<str>),
3637
37 FieldMustBeStringGot(ValType),38 FieldMustBeStringGot(ValType),
3839
modifiedcrates/jrsonnet-evaluator/src/evaluate.rsdiffbeforeafterboth
5 },5 },
6 context_creator, equals,6 context_creator, equals,
7 error::Error::*,7 error::Error::*,
8 future_wrapper, lazy_val, parse_args, primitive_equals, push, throw, with_state, Context,8 future_wrapper, lazy_val, parse_args, parse_function_call, primitive_equals, push, throw,
9 ContextCreator, FuncDesc, LazyBinding, LazyVal, LocError, ObjMember, ObjValue, Result, Val,9 with_state, Context, ContextCreator, FuncDesc, LazyBinding, LazyVal, LocError, ObjMember,
10 ValType,10 ObjValue, Result, Val, ValType,
11};11};
549 ], {549 ], {
550 Ok(Val::Num(x.powf(n)))550 Ok(Val::Num(x.powf(n)))
551 })?,551 })?,
552 ("std", "extVar") => parse_args!(context, "std.extVar", args, 2, [552 ("std", "extVar") => parse_args!(context, "std.extVar", args, 1, [
553 0, x: [Val::Str]!!Val::Str, vec![ValType::Str];553 0, x: [Val::Str]!!Val::Str, vec![ValType::Str];
554 ], {554 ], {
555 Ok(with_state(|s| s.settings().ext_vars.get(&x).cloned()).ok_or_else(555 Ok(with_state(|s| s.settings().ext_vars.get(&x).cloned()).ok_or_else(
556 || UndefinedExternalVariable(x),556 || UndefinedExternalVariable(x),
557 )?)557 )?)
558 })?,558 })?,
559 ("std", "native") => parse_args!(context, "std.native", args, 1, [
560 0, x: [Val::Str]!!Val::Str, vec![ValType::Str];
561 ], {
562 Ok(with_state(|s| s.settings().ext_natives.get(&x).cloned()).map(|v| Val::NativeExt(x.clone(), v)).ok_or_else(
563 || UndefinedExternalFunction(x),
564 )?)
565 })?,
559 ("std", "filter") => noinline!(parse_args!(context, "std.filter", args, 2, [566 ("std", "filter") => noinline!(parse_args!(context, "std.filter", args, 2, [
560 0, func: [Val::Func]!!Val::Func, vec![ValType::Func];567 0, func: [Val::Func]!!Val::Func, vec![ValType::Func];
561 1, arr: [Val::Arr]!!Val::Arr, vec![ValType::Arr];568 1, arr: [Val::Arr]!!Val::Arr, vec![ValType::Arr];
780 })787 })
781 },788 },
782 )?,789 )?,
790 Val::NativeExt(n, f) => push(
791 loc,
792 || format!("native <{}> call", n),
793 || {
794 let args = parse_function_call(context, None, &f.params, args, true)?;
795 let mut out_args = Vec::with_capacity(f.params.len());
796 for p in f.params.0.iter() {
797 out_args.push(args.binding(p.0.clone())?.evaluate()?);
798 }
799 Ok(f.call(&out_args)?)
800 },
801 )?,
783 Val::Func(f) => {802 Val::Func(f) => {
784 let body = || f.evaluate(context, args, tailstrict);803 let body = || f.evaluate(context, args, tailstrict);
785 if tailstrict {804 if tailstrict {
modifiedcrates/jrsonnet-evaluator/src/integrations/serde.rsdiffbeforeafterboth
40 }40 }
41 Value::Object(out)41 Value::Object(out)
42 }42 }
43 Val::Func(_) | Val::Intristic(_, _) => {43 Val::Func(_) | Val::Intristic(_, _) | Val::NativeExt(_, _) => {
44 throw!(RuntimeError("tried to manifest function".into()))44 throw!(RuntimeError("tried to manifest function".into()))
45 }45 }
46 })46 })
modifiedcrates/jrsonnet-evaluator/src/lib.rsdiffbeforeafterboth
10mod import;10mod import;
11mod integrations;11mod integrations;
12mod map;12mod map;
13pub mod native;
13mod obj;14mod obj;
14pub mod trace;15pub mod trace;
15mod val;16mod val;
21pub use function::parse_function_call;22pub use function::parse_function_call;
22pub use import::*;23pub use import::*;
23use jrsonnet_parser::*;24use jrsonnet_parser::*;
25use native::NativeCallback;
24pub use obj::*;26pub use obj::*;
25use std::{27use std::{
26 cell::{Ref, RefCell, RefMut},28 cell::{Ref, RefCell, RefMut},
60 pub max_trace: usize,62 pub max_trace: usize,
61 /// Used for std.extVar63 /// Used for std.extVar
62 pub ext_vars: HashMap<Rc<str>, Val>,64 pub ext_vars: HashMap<Rc<str>, Val>,
65 /// Used for ext.native
66 pub ext_natives: HashMap<Rc<str>, Rc<NativeCallback>>,
63 /// TLA vars67 /// TLA vars
64 pub tla_vars: HashMap<Rc<str>, Val>,68 pub tla_vars: HashMap<Rc<str>, Val>,
65 /// Global variables are inserted in default context69 /// Global variables are inserted in default context
78 max_trace: 20,82 max_trace: 20,
79 globals: Default::default(),83 globals: Default::default(),
80 ext_vars: Default::default(),84 ext_vars: Default::default(),
85 ext_natives: Default::default(),
81 tla_vars: Default::default(),86 tla_vars: Default::default(),
82 import_resolver: Box::new(DummyImportResolver),87 import_resolver: Box::new(DummyImportResolver),
83 manifest_format: ManifestFormat::Json(4),88 manifest_format: ManifestFormat::Json(4),
415 self.settings_mut().import_resolver = resolver;420 self.settings_mut().import_resolver = resolver;
416 }421 }
422
423 pub fn add_native(&self, name: Rc<str>, cb: Rc<NativeCallback>) {
424 self.settings_mut().ext_natives.insert(name, cb);
425 }
417426
418 pub fn manifest_format(&self) -> ManifestFormat {427 pub fn manifest_format(&self) -> ManifestFormat {
419 self.settings().manifest_format.clone()428 self.settings().manifest_format.clone()
851 assert_eval!("{ x: 1, y: 2 } == { x: 1, y: 2 }")860 assert_eval!("{ x: 1, y: 2 } == { x: 1, y: 2 }")
852 }861 }
862
863 #[test]
864 fn native_ext() -> crate::error::Result<()> {
865 use super::native::NativeCallback;
866 let evaluator = EvaluationState::default();
867
868 evaluator.with_stdlib();
869 evaluator.settings_mut().ext_natives.insert(
870 "native_add".into(),
871 Rc::new(NativeCallback::new(
872 ParamsDesc(Rc::new(vec![
873 Param("a".into(), None),
874 Param("b".into(), None),
875 ])),
876 |args| match (&args[0], &args[1]) {
877 (Val::Num(a), Val::Num(b)) => Ok(Val::Num(a + b)),
878 (_, _) => todo!(),
879 },
880 )),
881 );
882 evaluator.evaluate_snippet_raw(
883 Rc::new(PathBuf::from("test.jsonnet")),
884 "std.assertEqual(std.native(\"native_add\")(1, 2), 3)".into(),
885 )?;
886 Ok(())
887 }
853}888}
854889
addedcrates/jrsonnet-evaluator/src/native.rsdiffbeforeafterboth

no changes

modifiedcrates/jrsonnet-evaluator/src/val.rsdiffbeforeafterboth
3 error::Error::*,3 error::Error::*,
4 evaluate,4 evaluate,
5 function::{parse_function_call, parse_function_call_map, place_args},5 function::{parse_function_call, parse_function_call_map, place_args},
6 native::NativeCallback,
6 throw, with_state, Context, ObjValue, Result,7 throw, with_state, Context, ObjValue, Result,
7};8};
8use jrsonnet_parser::{el, Arg, ArgsDesc, Expr, LocExpr, ParamsDesc};9use jrsonnet_parser::{el, Arg, ArgsDesc, Expr, LocExpr, ParamsDesc};
152153
153 // Library functions implemented in native154 // Library functions implemented in native
154 Intristic(Rc<str>, Rc<str>),155 Intristic(Rc<str>, Rc<str>),
156 NativeExt(Rc<str>, Rc<NativeCallback>),
155}157}
156macro_rules! matches_unwrap {158macro_rules! matches_unwrap {
157 ($e: expr, $p: pat, $r: expr) => {159 ($e: expr, $p: pat, $r: expr) => {
204 Val::Num(..) => ValType::Num,206 Val::Num(..) => ValType::Num,
205 Val::Arr(..) => ValType::Arr,207 Val::Arr(..) => ValType::Arr,
206 Val::Obj(..) => ValType::Obj,208 Val::Obj(..) => ValType::Obj,
207 Val::Func(..) => ValType::Func,
208 Val::Bool(_) => ValType::Bool,209 Val::Bool(_) => ValType::Bool,
209 Val::Null => ValType::Null,210 Val::Null => ValType::Null,
210 Val::Intristic(_, _) => ValType::Func,211 Val::Func(..) | Val::Intristic(_, _) | Val::NativeExt(_, _) => ValType::Func,
211 Val::Lazy(_) => self.clone().unwrap_if_lazy()?.value_type()?,212 Val::Lazy(_) => self.clone().unwrap_if_lazy()?.value_type()?,
212 })213 })
213 }214 }
343}344}
344345
345fn is_function_like(val: &Val) -> bool {346fn is_function_like(val: &Val) -> bool {
346 matches!(val, Val::Func(_) | Val::Intristic(_, _))347 matches!(val, Val::Func(_) | Val::Intristic(_, _) | Val::NativeExt(_, _))
347}348}
348349
349/// Implements std.primitiveEquals builtin350/// Implements std.primitiveEquals builtin