use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::OnceLock;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Layer {
Builtin,
ImportedFile,
WholeExpression,
}
impl Layer {
#[must_use]
pub fn name(self) -> &'static str {
match self {
Layer::Builtin => "builtin",
Layer::ImportedFile => "imported-file",
Layer::WholeExpression => "whole-expression",
}
}
#[must_use]
pub fn is_fatal_under_strict(self) -> bool {
match self {
Layer::Builtin => false,
Layer::ImportedFile | Layer::WholeExpression => true,
}
}
pub const ALL: &'static [Layer] = &[
Layer::Builtin,
Layer::ImportedFile,
Layer::WholeExpression,
];
}
static BUILTIN: AtomicU64 = AtomicU64::new(0);
static IMPORTED_FILE: AtomicU64 = AtomicU64::new(0);
static WHOLE_EXPRESSION: AtomicU64 = AtomicU64::new(0);
fn cell(layer: Layer) -> &'static AtomicU64 {
match layer {
Layer::Builtin => &BUILTIN,
Layer::ImportedFile => &IMPORTED_FILE,
Layer::WholeExpression => &WHOLE_EXPRESSION,
}
}
#[must_use]
pub fn strict() -> bool {
static ON: OnceLock<bool> = OnceLock::new();
*ON.get_or_init(|| std::env::var("SUI_VM_STRICT").as_deref() == Ok("1"))
}
pub fn record(layer: Layer, detail: &str) -> Result<(), String> {
cell(layer).fetch_add(1, Ordering::Relaxed);
if strict() && layer.is_fatal_under_strict() {
return Err(format!(
"SUI_VM_STRICT: refusing to fall back to the tree-walker at the \
{} boundary: {detail}. Strict mode exists so a measurement cannot \
silently become the walker's answer — if you want the fallback, \
unset SUI_VM_STRICT; if you want the VM to handle this, that is \
the bug.",
layer.name()
));
}
Ok(())
}
#[must_use]
pub fn count(layer: Layer) -> u64 {
cell(layer).load(Ordering::Relaxed)
}
#[must_use]
pub fn total() -> u64 {
Layer::ALL.iter().map(|l| count(*l)).sum()
}
#[must_use]
pub fn report() -> String {
Layer::ALL
.iter()
.map(|l| format!("{}={}", l.name(), count(*l)))
.collect::<Vec<_>>()
.join(" ")
}
pub fn reset() {
for l in Layer::ALL {
cell(*l).store(0, Ordering::Relaxed);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn builtin_bridging_is_never_fatal() {
assert!(!Layer::Builtin.is_fatal_under_strict());
assert!(record(Layer::Builtin, "getEnv").is_ok());
}
#[test]
fn the_two_failure_layers_are_fatal_under_strict() {
assert!(Layer::ImportedFile.is_fatal_under_strict());
assert!(Layer::WholeExpression.is_fatal_under_strict());
}
#[test]
fn counting_happens_whether_or_not_strict_is_on() {
let before = count(Layer::Builtin);
let _ = record(Layer::Builtin, "probe");
assert_eq!(count(Layer::Builtin), before + 1);
}
#[test]
fn report_names_every_layer() {
let r = report();
for l in Layer::ALL {
assert!(r.contains(l.name()), "report() omits {}", l.name());
}
assert_eq!(Layer::ALL.len(), 3, "a layer was added or removed");
}
}