This adds static strings to generator frames that describe the generator in a human-readable fashion, which are then logged in observers. This makes runtime traces very precise, explaining exactly what is being requested from where. Change-Id: I695659a6bd0b7b0bdee75bc8049651f62b150e0c Reviewed-on: https://cl.tvl.fyi/c/depot/+/8206 Tested-by: BuildkiteCI Reviewed-by: raitobezarius <tvl@lahfa.xyz>
70 lines
2.4 KiB
Rust
70 lines
2.4 KiB
Rust
/// This module provides macros which are used in the implementation
|
|
/// of the VM for the implementation of repetitive operations.
|
|
|
|
/// This macro simplifies the implementation of arithmetic operations,
|
|
/// correctly handling the behaviour on different pairings of number
|
|
/// types.
|
|
#[macro_export]
|
|
macro_rules! arithmetic_op {
|
|
( $self:ident, $op:tt ) => {{ // TODO: remove
|
|
let b = $self.pop();
|
|
let a = $self.pop();
|
|
let result = fallible!($self, arithmetic_op!(&a, &b, $op));
|
|
$self.push(result);
|
|
}};
|
|
|
|
( $a:expr, $b:expr, $op:tt ) => {{
|
|
match ($a, $b) {
|
|
(Value::Integer(i1), Value::Integer(i2)) => Ok(Value::Integer(i1 $op i2)),
|
|
(Value::Float(f1), Value::Float(f2)) => Ok(Value::Float(f1 $op f2)),
|
|
(Value::Integer(i1), Value::Float(f2)) => Ok(Value::Float(*i1 as f64 $op f2)),
|
|
(Value::Float(f1), Value::Integer(i2)) => Ok(Value::Float(f1 $op *i2 as f64)),
|
|
|
|
(v1, v2) => Err(ErrorKind::TypeError {
|
|
expected: "number (either int or float)",
|
|
actual: if v1.is_number() {
|
|
v2.type_of()
|
|
} else {
|
|
v1.type_of()
|
|
},
|
|
}),
|
|
}
|
|
}};
|
|
}
|
|
|
|
/// This macro simplifies the implementation of comparison operations.
|
|
#[macro_export]
|
|
macro_rules! cmp_op {
|
|
( $vm:ident, $frame:ident, $span:ident, $op:tt ) => {{
|
|
let b = $vm.stack_pop();
|
|
let a = $vm.stack_pop();
|
|
|
|
async fn compare(a: Value, b: Value, co: GenCo) -> Result<Value, ErrorKind> {
|
|
let a = generators::request_force(&co, a).await;
|
|
let b = generators::request_force(&co, b).await;
|
|
let ordering = a.nix_cmp_ordering(b, co).await?;
|
|
Ok(Value::Bool(cmp_op!(@order $op ordering)))
|
|
}
|
|
|
|
let gen_span = $frame.current_light_span();
|
|
$vm.push_call_frame($span, $frame);
|
|
$vm.enqueue_generator("compare", gen_span, |co| compare(a, b, co));
|
|
return Ok(false);
|
|
}};
|
|
|
|
(@order < $ordering:expr) => {
|
|
$ordering == Some(Ordering::Less)
|
|
};
|
|
|
|
(@order > $ordering:expr) => {
|
|
$ordering == Some(Ordering::Greater)
|
|
};
|
|
|
|
(@order <= $ordering:expr) => {
|
|
!matches!($ordering, None | Some(Ordering::Greater))
|
|
};
|
|
|
|
(@order >= $ordering:expr) => {
|
|
!matches!($ordering, None | Some(Ordering::Less))
|
|
};
|
|
}
|