cleanup: Remove EvalState::new_value_function
It provides not so great values for some of the parameters, and we don't really need its convenience. (cherry picked from commit 52b7b58eb7fa96a265883cbf92e3a635735fe360)
This commit is contained in:
parent
312c86b811
commit
da9bb4c885
1 changed files with 90 additions and 82 deletions
|
|
@ -9,7 +9,7 @@ use nix_store::store::{Store, StoreWeak};
|
||||||
use nix_util::context::Context;
|
use nix_util::context::Context;
|
||||||
use nix_util::string_return::{callback_get_result_string, callback_get_result_string_data};
|
use nix_util::string_return::{callback_get_result_string, callback_get_result_string_data};
|
||||||
use nix_util::{check_call, check_call_opt_key, result_string_init};
|
use nix_util::{check_call, check_call_opt_key, result_string_init};
|
||||||
use std::ffi::{c_char, CStr, CString};
|
use std::ffi::{c_char, CString};
|
||||||
use std::os::raw::c_uint;
|
use std::os::raw::c_uint;
|
||||||
use std::ptr::{null, null_mut, NonNull};
|
use std::ptr::{null, null_mut, NonNull};
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
|
|
@ -416,16 +416,6 @@ impl EvalState {
|
||||||
Ok(Value::new(value))
|
Ok(Value::new(value))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn thunk(&mut self, f: Box<dyn Fn(&mut EvalState) -> Result<Value>>) -> Result<Value> {
|
|
||||||
// Nix doesn't have a function for creating a thunk, so we have to
|
|
||||||
// create a function and pass it a dummy argument.
|
|
||||||
let f = self.new_value_function(
|
|
||||||
FUNCTION_ANONYMOUS.as_ptr(),
|
|
||||||
Box::new(move |eval_state, _dummy: &[Value; 1]| f(eval_state)),
|
|
||||||
)?;
|
|
||||||
self.new_value_apply(&f, &f)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a new Nix function that is implemented by a Rust function.
|
/// Create a new Nix function that is implemented by a Rust function.
|
||||||
/// This is also known as a "primop" in Nix, short for primitive operation.
|
/// This is also known as a "primop" in Nix, short for primitive operation.
|
||||||
/// Most of the `builtins.*` values are examples of primops, but
|
/// Most of the `builtins.*` values are examples of primops, but
|
||||||
|
|
@ -441,38 +431,6 @@ impl EvalState {
|
||||||
};
|
};
|
||||||
Ok(value)
|
Ok(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A worse quality shortcut for calling [new_value_primop].
|
|
||||||
pub fn new_value_function<const N: usize>(
|
|
||||||
&mut self,
|
|
||||||
name: *const i8,
|
|
||||||
f: Box<dyn Fn(&mut EvalState, &[Value; N]) -> Result<Value>>,
|
|
||||||
) -> Result<Value> {
|
|
||||||
if N == 0 {
|
|
||||||
return self.thunk(Box::new(move |eval_state| {
|
|
||||||
f(eval_state, {
|
|
||||||
let empty: &[Value] = &[];
|
|
||||||
empty.try_into().unwrap()
|
|
||||||
})
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
let name = unsafe { CStr::from_ptr(name) };
|
|
||||||
|
|
||||||
let args: [&CStr; N] = [FUNCTION_ANONYMOUS_ARG.as_ref(); N];
|
|
||||||
|
|
||||||
let prim = primop::PrimOp::new(
|
|
||||||
self,
|
|
||||||
primop::PrimOpMeta {
|
|
||||||
name,
|
|
||||||
args,
|
|
||||||
doc: FUNCTION_ANONYMOUS_DOC.as_ref(),
|
|
||||||
},
|
|
||||||
f,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
self.new_value_primop(prim)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gc_now() {
|
pub fn gc_now() {
|
||||||
|
|
@ -527,11 +485,6 @@ impl Clone for EvalState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy_static! {
|
|
||||||
pub static ref FUNCTION_ANONYMOUS: CString = CString::new("anonymous-primop").unwrap();
|
|
||||||
static ref FUNCTION_ANONYMOUS_ARG: CString = CString::new("x").unwrap();
|
|
||||||
static ref FUNCTION_ANONYMOUS_DOC: CString = CString::new("anonymous primop").unwrap();
|
|
||||||
}
|
|
||||||
/// Initialize the Nix library for testing. This includes some modifications to the Nix settings, that must not be used in production.
|
/// Initialize the Nix library for testing. This includes some modifications to the Nix settings, that must not be used in production.
|
||||||
/// Use at your own peril, in rust test suites.
|
/// Use at your own peril, in rust test suites.
|
||||||
pub fn test_init() {
|
pub fn test_init() {
|
||||||
|
|
@ -555,6 +508,7 @@ mod tests {
|
||||||
use cstr::cstr;
|
use cstr::cstr;
|
||||||
use ctor::ctor;
|
use ctor::ctor;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::ffi::CStr;
|
||||||
use std::fs::read_dir;
|
use std::fs::read_dir;
|
||||||
use std::io::Write as _;
|
use std::io::Write as _;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
@ -564,6 +518,60 @@ mod tests {
|
||||||
test_init();
|
test_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
pub static ref FUNCTION_ANONYMOUS: CString = CString::new("anonymous-primop").unwrap();
|
||||||
|
static ref FUNCTION_ANONYMOUS_ARG: CString = CString::new("x").unwrap();
|
||||||
|
static ref FUNCTION_ANONYMOUS_DOC: CString = CString::new("anonymous primop").unwrap();
|
||||||
|
}
|
||||||
|
pub fn thunk(
|
||||||
|
es: &mut EvalState,
|
||||||
|
f: Box<dyn Fn(&mut EvalState) -> Result<Value>>,
|
||||||
|
) -> Result<Value> {
|
||||||
|
// Nix doesn't have a function for creating a thunk, so we have to
|
||||||
|
// create a function and pass it a dummy argument.
|
||||||
|
let f = new_value_function(
|
||||||
|
es,
|
||||||
|
FUNCTION_ANONYMOUS.as_ptr(),
|
||||||
|
Box::new(move |eval_state, _dummy: &[Value; 1]| f(eval_state)),
|
||||||
|
)?;
|
||||||
|
es.new_value_apply(&f, &f)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A worse quality shortcut for calling [new_value_primop].
|
||||||
|
pub fn new_value_function<const N: usize>(
|
||||||
|
es: &mut EvalState,
|
||||||
|
name: *const i8,
|
||||||
|
f: Box<dyn Fn(&mut EvalState, &[Value; N]) -> Result<Value>>,
|
||||||
|
) -> Result<Value> {
|
||||||
|
if N == 0 {
|
||||||
|
return thunk(
|
||||||
|
es,
|
||||||
|
Box::new(move |eval_state| {
|
||||||
|
f(eval_state, {
|
||||||
|
let empty: &[Value] = &[];
|
||||||
|
empty.try_into().unwrap()
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let name = unsafe { CStr::from_ptr(name) };
|
||||||
|
|
||||||
|
let args: [&CStr; N] = [FUNCTION_ANONYMOUS_ARG.as_ref(); N];
|
||||||
|
|
||||||
|
let prim = primop::PrimOp::new(
|
||||||
|
es,
|
||||||
|
primop::PrimOpMeta {
|
||||||
|
name,
|
||||||
|
args,
|
||||||
|
doc: FUNCTION_ANONYMOUS_DOC.as_ref(),
|
||||||
|
},
|
||||||
|
f,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
es.new_value_primop(prim)
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn eval_state_new_and_drop() {
|
fn eval_state_new_and_drop() {
|
||||||
gc_registering_current_thread(|| {
|
gc_registering_current_thread(|| {
|
||||||
|
|
@ -1342,17 +1350,17 @@ mod tests {
|
||||||
let mut es = EvalState::new(store, []).unwrap();
|
let mut es = EvalState::new(store, []).unwrap();
|
||||||
let bias: Arc<Mutex<Int>> = Arc::new(Mutex::new(0));
|
let bias: Arc<Mutex<Int>> = Arc::new(Mutex::new(0));
|
||||||
let bias_control = bias.clone();
|
let bias_control = bias.clone();
|
||||||
let f = es
|
let f = new_value_function(
|
||||||
.new_value_function(
|
&mut es,
|
||||||
FUNCTION_ANONYMOUS.as_ptr(),
|
FUNCTION_ANONYMOUS.as_ptr(),
|
||||||
Box::new(move |es, [a, b]| {
|
Box::new(move |es, [a, b]| {
|
||||||
let a = es.require_int(a)?;
|
let a = es.require_int(a)?;
|
||||||
let b = es.require_int(b)?;
|
let b = es.require_int(b)?;
|
||||||
let c = *bias.lock().unwrap();
|
let c = *bias.lock().unwrap();
|
||||||
Ok(es.new_value_int(a + b + c)?)
|
Ok(es.new_value_int(a + b + c)?)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
{
|
{
|
||||||
*bias_control.lock().unwrap() = 10;
|
*bias_control.lock().unwrap() = 10;
|
||||||
}
|
}
|
||||||
|
|
@ -1374,15 +1382,15 @@ mod tests {
|
||||||
gc_registering_current_thread(|| {
|
gc_registering_current_thread(|| {
|
||||||
let store = Store::open("auto", []).unwrap();
|
let store = Store::open("auto", []).unwrap();
|
||||||
let mut es = EvalState::new(store, []).unwrap();
|
let mut es = EvalState::new(store, []).unwrap();
|
||||||
let f = es
|
let f = new_value_function(
|
||||||
.new_value_function(
|
&mut es,
|
||||||
FUNCTION_ANONYMOUS.as_ptr(),
|
FUNCTION_ANONYMOUS.as_ptr(),
|
||||||
Box::new(move |es, [a]| {
|
Box::new(move |es, [a]| {
|
||||||
let a = es.require_int(a)?;
|
let a = es.require_int(a)?;
|
||||||
bail!("error with arg [{}]", a);
|
bail!("error with arg [{}]", a);
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let a = es.new_value_int(2).unwrap();
|
let a = es.new_value_int(2).unwrap();
|
||||||
let r = es.call(f, a);
|
let r = es.call(f, a);
|
||||||
match r {
|
match r {
|
||||||
|
|
@ -1403,12 +1411,12 @@ mod tests {
|
||||||
gc_registering_current_thread(|| {
|
gc_registering_current_thread(|| {
|
||||||
let store = Store::open("auto", []).unwrap();
|
let store = Store::open("auto", []).unwrap();
|
||||||
let mut es = EvalState::new(store, []).unwrap();
|
let mut es = EvalState::new(store, []).unwrap();
|
||||||
let v = es
|
let v = new_value_function(
|
||||||
.new_value_function(
|
&mut es,
|
||||||
FUNCTION_ANONYMOUS.as_ptr(),
|
FUNCTION_ANONYMOUS.as_ptr(),
|
||||||
Box::new(move |es, []| Ok(es.new_value_int(42)?)),
|
Box::new(move |es, []| Ok(es.new_value_int(42)?)),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
es.force(&v).unwrap();
|
es.force(&v).unwrap();
|
||||||
let t = es.value_type(&v).unwrap();
|
let t = es.value_type(&v).unwrap();
|
||||||
eprintln!("{:?}", t);
|
eprintln!("{:?}", t);
|
||||||
|
|
@ -1424,14 +1432,14 @@ mod tests {
|
||||||
gc_registering_current_thread(|| {
|
gc_registering_current_thread(|| {
|
||||||
let store = Store::open("auto", []).unwrap();
|
let store = Store::open("auto", []).unwrap();
|
||||||
let mut es = EvalState::new(store, []).unwrap();
|
let mut es = EvalState::new(store, []).unwrap();
|
||||||
let v = es
|
let v = new_value_function(
|
||||||
.new_value_function(
|
&mut es,
|
||||||
FUNCTION_ANONYMOUS.as_ptr(),
|
FUNCTION_ANONYMOUS.as_ptr(),
|
||||||
Box::new(move |_es, []| {
|
Box::new(move |_es, []| {
|
||||||
bail!("error message in test case eval_state_primop_anon_call_no_args_lazy")
|
bail!("error message in test case eval_state_primop_anon_call_no_args_lazy")
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let r = es.force(&v);
|
let r = es.force(&v);
|
||||||
match r {
|
match r {
|
||||||
Ok(_) => panic!("expected an error"),
|
Ok(_) => panic!("expected an error"),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue