guard: add motes and use in all errors; disable sigint handling

This commit is contained in:
Matthew LeVan 2024-01-24 15:30:19 -05:00
parent a0ddc1f89c
commit fa316f664b
12 changed files with 185 additions and 253 deletions

View File

@ -312,12 +312,20 @@ impl Context {
}
}
#[derive(Clone, Copy, Debug)]
pub enum Mote {
Exit = tas!(b"exit") as isize,
Fail = tas!(b"fail") as isize,
Intr = tas!(b"intr") as isize,
Meme = tas!(b"meme") as isize,
}
#[derive(Clone, Copy, Debug)]
pub enum Error {
ScryBlocked(Noun), // path
ScryCrashed(Noun), // trace
Deterministic(Noun), // trace
NonDeterministic(Noun), // trace
ScryBlocked(Noun), // path
ScryCrashed(Noun), // trace
Deterministic(Mote, Noun), // mote, trace
NonDeterministic(Mote, Noun), // mote, trace
}
pub enum GuardError {
@ -347,8 +355,8 @@ impl Preserve for Error {
match self {
Error::ScryBlocked(ref mut path) => path.preserve(stack),
Error::ScryCrashed(ref mut trace) => trace.preserve(stack),
Error::Deterministic(ref mut trace) => trace.preserve(stack),
Error::NonDeterministic(ref mut trace) => trace.preserve(stack),
Error::Deterministic(_, ref mut trace) => trace.preserve(stack),
Error::NonDeterministic(_, ref mut trace) => trace.preserve(stack),
}
}
@ -356,26 +364,28 @@ impl Preserve for Error {
match self {
Error::ScryBlocked(ref path) => path.assert_in_stack(stack),
Error::ScryCrashed(ref trace) => trace.assert_in_stack(stack),
Error::Deterministic(ref trace) => trace.assert_in_stack(stack),
Error::NonDeterministic(ref trace) => trace.assert_in_stack(stack),
Error::Deterministic(_, ref trace) => trace.assert_in_stack(stack),
Error::NonDeterministic(_, ref trace) => trace.assert_in_stack(stack),
}
}
}
impl From<noun::Error> for Error {
fn from(_: noun::Error) -> Self {
Error::Deterministic(D(0))
Error::Deterministic(Mote::Exit, D(0))
}
}
impl From<cold::Error> for Error {
fn from(_: cold::Error) -> Self {
Error::Deterministic(D(0))
Error::Deterministic(Mote::Exit, D(0))
}
}
pub type Result = result::Result<Noun, Error>;
const BAIL_EXIT: Result = Err(Error::Deterministic(Mote::Exit, D(0)));
#[allow(unused_variables)]
fn debug_assertions(stack: &mut NockStack, noun: Noun) {
assert_acyclic!(noun);
@ -461,20 +471,20 @@ pub fn call_with_guard<F: FnMut() -> Result>(
return result;
}
GuardError::GuardArmor => {
return Err(Error::Deterministic(D(0)));
return Err(Error::Deterministic(Mote::Exit, D(0)));
}
GuardError::GuardWeird => {
return Err(Error::Deterministic(D(0)));
return Err(Error::Deterministic(Mote::Exit, D(0)));
}
GuardError::GuardSpent => {
return Err(Error::NonDeterministic(D(0)));
return Err(Error::NonDeterministic(Mote::Meme, D(0)));
}
GuardError::GuardErupt => {
return Err(Error::NonDeterministic(D(0)));
return Err(Error::NonDeterministic(Mote::Intr, D(0)));
}
}
} else {
return Err(Error::Deterministic(D(0)));
return Err(Error::Deterministic(Mote::Exit, D(0)));
}
}
}
@ -486,21 +496,21 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
let snapshot = context.save();
let virtual_frame: *const u64 = context.stack.get_frame_pointer();
let mut res: Noun = D(0);
let stack_ptr = context.stack.get_stack_pointer() as *mut c_void;
let stack_ptr_ptr = &stack_ptr as *const *mut c_void;
let alloc_ptr = context.stack.get_alloc_pointer() as *mut c_void;
let alloc_ptr_ptr = &alloc_ptr as *const *mut c_void;
let stack_p = context.stack.get_stack_pointer() as *mut c_void;
let alloc_p = context.stack.get_alloc_pointer() as *mut c_void;
let stack_pp = &stack_p as *const *mut c_void;
let alloc_pp = &alloc_p as *const *mut c_void;
// Setup stack for Nock computation
unsafe {
context.stack.frame_push(2);
(*context).stack.frame_push(2);
// Bottom of mean stack
*(context.stack.local_noun_pointer(0)) = D(0);
*((*context).stack.local_noun_pointer(0)) = D(0);
// Bottom of trace stack
*(context.stack.local_noun_pointer(1) as *mut *const TraceStack) = std::ptr::null();
*((*context).stack.local_noun_pointer(1) as *mut *const TraceStack) = std::ptr::null();
*(context.stack.push()) = NockWork::Done;
*((*context).stack.push()) = NockWork::Done;
};
// DO NOT REMOVE THIS ASSERTION
@ -526,7 +536,6 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
write_trace(context);
let stack = &mut context.stack;
debug_assertions(stack, orig_subject);
debug_assertions(stack, subject);
debug_assertions(stack, res);
@ -582,7 +591,7 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
context.stack.pop::<NockWork>();
} else {
// Axis invalid for input Noun
break Err(Error::Deterministic(D(0)));
break BAIL_EXIT;
}
}
NockWork::Work1(once) => {
@ -591,7 +600,7 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
}
NockWork::Work2(mut vale) => {
if (*terminator).load(Ordering::Relaxed) {
break Err(Error::NonDeterministic(D(0)));
break Err(Error::NonDeterministic(Mote::Intr, D(0)));
}
match vale.todo {
@ -661,7 +670,7 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
context.stack.pop::<NockWork>();
} else {
// Cannot increment (Nock 4) a cell
break Err(Error::Deterministic(D(0)));
break BAIL_EXIT;
}
}
},
@ -704,11 +713,11 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
push_formula(stack, cond.once, cond.tail)?;
} else {
// Test branch of Nock 6 must return 0 or 1
break Err(Error::Deterministic(D(0)));
break BAIL_EXIT;
}
} else {
// Test branch of Nock 6 must return a direct atom
break Err(Error::Deterministic(D(0)));
break BAIL_EXIT;
}
}
},
@ -764,7 +773,7 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
},
NockWork::Work9(mut kale) => {
if (*terminator).load(Ordering::Relaxed) {
break Err(Error::NonDeterministic(D(0)));
break Err(Error::NonDeterministic(Mote::Intr, D(0)));
}
match kale.todo {
@ -839,7 +848,7 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
}
} else {
// Axis into core must be atom
break Err(Error::Deterministic(D(0)));
break BAIL_EXIT;
}
}
Todo9::RestoreSubject => {
@ -1042,28 +1051,31 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
}
},
Err(error) => match error {
Error::Deterministic(trace)
Error::Deterministic(_, trace)
| Error::ScryCrashed(trace) => {
break Err(Error::ScryCrashed(trace));
}
Error::NonDeterministic(_) => {
Error::NonDeterministic(_, _) => {
break Err(error);
}
Error::ScryBlocked(_) => {
break Err(Error::NonDeterministic(D(0)));
break Err(Error::NonDeterministic(
Mote::Fail,
D(0),
));
}
},
}
} else {
// No scry handler
break Err(Error::Deterministic(D(0)));
break BAIL_EXIT;
}
}
},
};
}
};
call_with_guard(work_closure, stack_ptr_ptr, alloc_ptr_ptr)
call_with_guard(work_closure, stack_pp, alloc_pp)
})
});
@ -1073,7 +1085,7 @@ pub fn interpret(context: &mut Context, mut subject: Noun, formula: Noun) -> Res
}
}
fn push_formula(stack: &mut NockStack, formula: Noun, tail: bool) -> result::Result<(), Error> {
fn push_formula(stack: &mut NockStack, formula: Noun, tail: bool) -> Result {
unsafe {
if let Ok(formula_cell) = formula.as_cell() {
// Formula
@ -1093,7 +1105,7 @@ fn push_formula(stack: &mut NockStack, formula: Noun, tail: bool) -> result::Res
*stack.push() = NockWork::Work0(Nock0 { axis: axis_atom });
} else {
// Axis for Nock 0 must be an atom
return Err(Error::Deterministic(D(0)));
return BAIL_EXIT;
}
}
1 => {
@ -1111,7 +1123,7 @@ fn push_formula(stack: &mut NockStack, formula: Noun, tail: bool) -> result::Res
});
} else {
// Argument to Nock 2 must be cell
return Err(Error::Deterministic(D(0)));
return BAIL_EXIT;
};
}
3 => {
@ -1135,7 +1147,7 @@ fn push_formula(stack: &mut NockStack, formula: Noun, tail: bool) -> result::Res
});
} else {
// Argument to Nock 5 must be cell
return Err(Error::Deterministic(D(0)));
return BAIL_EXIT;
};
}
6 => {
@ -1150,11 +1162,11 @@ fn push_formula(stack: &mut NockStack, formula: Noun, tail: bool) -> result::Res
});
} else {
// Argument tail to Nock 6 must be cell
return Err(Error::Deterministic(D(0)));
return BAIL_EXIT;
};
} else {
// Argument to Nock 6 must be cell
return Err(Error::Deterministic(D(0)));
return BAIL_EXIT;
}
}
7 => {
@ -1167,7 +1179,7 @@ fn push_formula(stack: &mut NockStack, formula: Noun, tail: bool) -> result::Res
});
} else {
// Argument to Nock 7 must be cell
return Err(Error::Deterministic(D(0)));
return BAIL_EXIT;
};
}
8 => {
@ -1180,7 +1192,7 @@ fn push_formula(stack: &mut NockStack, formula: Noun, tail: bool) -> result::Res
});
} else {
// Argument to Nock 8 must be cell
return Err(Error::Deterministic(D(0)));
return BAIL_EXIT;
};
}
9 => {
@ -1194,11 +1206,11 @@ fn push_formula(stack: &mut NockStack, formula: Noun, tail: bool) -> result::Res
});
} else {
// Axis for Nock 9 must be an atom
return Err(Error::Deterministic(D(0)));
return BAIL_EXIT;
}
} else {
// Argument to Nock 9 must be cell
return Err(Error::Deterministic(D(0)));
return BAIL_EXIT;
};
}
10 => {
@ -1213,15 +1225,15 @@ fn push_formula(stack: &mut NockStack, formula: Noun, tail: bool) -> result::Res
});
} else {
// Axis for Nock 10 must be an atom
return Err(Error::Deterministic(D(0)));
return BAIL_EXIT;
}
} else {
// Heah of argument to Nock 10 must be a cell
return Err(Error::Deterministic(D(0)));
return BAIL_EXIT;
};
} else {
// Argument to Nock 10 must be a cell
return Err(Error::Deterministic(D(0)));
return BAIL_EXIT;
};
}
11 => {
@ -1246,13 +1258,13 @@ fn push_formula(stack: &mut NockStack, formula: Noun, tail: bool) -> result::Res
});
} else {
// Hint tag must be an atom
return Err(Error::Deterministic(D(0)));
return BAIL_EXIT;
}
}
};
} else {
// Argument for Nock 11 must be cell
return Err(Error::Deterministic(D(0)));
return BAIL_EXIT;
};
}
12 => {
@ -1264,26 +1276,26 @@ fn push_formula(stack: &mut NockStack, formula: Noun, tail: bool) -> result::Res
});
} else {
// Argument for Nock 12 must be cell
return Err(Error::Deterministic(D(0)));
return BAIL_EXIT;
}
}
_ => {
// Invalid formula opcode
return Err(Error::Deterministic(D(0)));
return BAIL_EXIT;
}
}
} else {
// Formula opcode must be direct atom
return Err(Error::Deterministic(D(0)));
return BAIL_EXIT;
}
}
}
} else {
// Bad formula: atoms are not formulas
return Err(Error::Deterministic(D(0)));
return BAIL_EXIT;
}
}
Ok(())
Ok(D(0))
}
fn exit(
@ -1298,7 +1310,7 @@ fn exit(
let stack = &mut context.stack;
let mut preserve = match error {
Error::ScryBlocked(path) => path,
Error::Deterministic(t) | Error::NonDeterministic(t) | Error::ScryCrashed(t) => {
Error::Deterministic(_, t) | Error::NonDeterministic(_, t) | Error::ScryCrashed(t) => {
// Return $tang of traces
let h = *(stack.local_noun_pointer(0));
T(stack, &[h, t])
@ -1311,8 +1323,8 @@ fn exit(
}
match error {
Error::Deterministic(_) => Error::Deterministic(preserve),
Error::NonDeterministic(_) => Error::NonDeterministic(preserve),
Error::Deterministic(mote, _) => Error::Deterministic(mote, preserve),
Error::NonDeterministic(mote, _) => Error::NonDeterministic(mote, preserve),
Error::ScryCrashed(_) => Error::ScryCrashed(preserve),
Error::ScryBlocked(_) => error,
}
@ -1512,7 +1524,7 @@ mod hint {
// let tape = tape(stack, "jet mismatch in {}, raw: {}, jetted: {}", jet_name, nock_res, jet_res);
// let mean = T(stack, &[D(tas!(b"mean")), tape]);
// mean_push(stack, mean);
Some(Err(Error::Deterministic(D(0))))
Some(BAIL_EXIT)
} else {
Some(Ok(nock_res))
}
@ -1525,10 +1537,10 @@ mod hint {
// mean_push(stack, mean);
match error {
Error::NonDeterministic(_) => {
Some(Err(Error::NonDeterministic(D(0))))
Error::NonDeterministic(mote, _) => {
Some(Err(Error::NonDeterministic(mote, D(0))))
}
_ => Some(Err(Error::Deterministic(D(0)))),
_ => Some(BAIL_EXIT),
}
}
}
@ -1586,7 +1598,7 @@ mod hint {
tas!(b"hand") | tas!(b"hunk") | tas!(b"lose") | tas!(b"mean") | tas!(b"spot") => {
let terminator = Arc::clone(&TERMINATOR);
if (*terminator).load(Ordering::Relaxed) {
return Some(Err(Error::NonDeterministic(D(0))));
return Some(Err(Error::NonDeterministic(Mote::Intr, D(0))));
}
let stack = &mut context.stack;

View File

@ -15,7 +15,7 @@ pub mod serial;
pub mod sort;
pub mod tree;
use crate::interpreter::{Context, Error};
use crate::interpreter::{Context, Error, Mote};
use crate::jets::bits::*;
use crate::jets::cold::Cold;
use crate::jets::form::*;
@ -79,7 +79,7 @@ impl From<Error> for JetErr {
impl From<noun::Error> for JetErr {
fn from(_err: noun::Error) -> Self {
Self::Fail(Error::Deterministic(D(0)))
Self::Fail(Error::Deterministic(Mote::Exit, D(0)))
}
}
@ -190,6 +190,9 @@ pub mod util {
use bitvec::prelude::{BitSlice, Lsb0};
use std::result;
pub const BAIL_EXIT: JetErr = JetErr::Fail(Error::Deterministic(Mote::Exit, D(0)));
pub const BAIL_FAIL: JetErr = JetErr::Fail(Error::NonDeterministic(Mote::Fail, D(0)));
/**
* Address-based size checks.
* Currently, only addresses indexable by the first 48 bits are reachable by
@ -201,13 +204,12 @@ pub mod util {
pub fn checked_add(a: usize, b: usize) -> result::Result<usize, JetErr> {
a.checked_add(b)
.filter(|x| x <= &MAX_BIT_LENGTH)
.ok_or(JetErr::Fail(Error::NonDeterministic(D(0))))
.ok_or(BAIL_FAIL)
}
/// Performs subtraction that returns None on Noun size overflow
pub fn checked_sub(a: usize, b: usize) -> result::Result<usize, JetErr> {
a.checked_sub(b)
.ok_or(JetErr::Fail(Error::NonDeterministic(D(0))))
a.checked_sub(b).ok_or(BAIL_FAIL)
}
pub fn checked_left_shift(bloq: usize, a: usize) -> result::Result<usize, JetErr> {
@ -215,7 +217,7 @@ pub mod util {
// Catch overflow
if (res >> bloq) < a || res > MAX_BIT_LENGTH {
Err(JetErr::Fail(Error::NonDeterministic(D(0))))
Err(BAIL_FAIL)
} else {
Ok(res)
}
@ -232,15 +234,14 @@ pub mod util {
}
pub fn slot(noun: Noun, axis: u64) -> Result {
noun.slot(axis)
.map_err(|_e| JetErr::Fail(Error::Deterministic(D(0))))
noun.slot(axis).map_err(|_e| BAIL_EXIT)
}
/// Extract a bloq and check that it's computable by the current system
pub fn bloq(a: Noun) -> result::Result<usize, JetErr> {
let bloq = a.as_direct()?.data() as usize;
if bloq >= 47 {
Err(JetErr::Fail(Error::NonDeterministic(D(0))))
Err(BAIL_FAIL)
} else {
Ok(bloq)
}
@ -380,10 +381,13 @@ pub mod util {
match (actual_err, expected_err) {
(Error::ScryBlocked(mut actual), Error::ScryBlocked(mut expected))
| (Error::ScryCrashed(mut actual), Error::ScryCrashed(mut expected))
| (Error::Deterministic(mut actual), Error::Deterministic(mut expected))
| (
Error::NonDeterministic(mut actual),
Error::NonDeterministic(mut expected),
Error::Deterministic(_, mut actual),
Error::Deterministic(_, mut expected),
)
| (
Error::NonDeterministic(_, mut actual),
Error::NonDeterministic(_, mut expected),
) => unsafe {
assert!(unifying_equality(
&mut context.stack,

View File

@ -1,8 +1,8 @@
/** Bit arithmetic & logic jets
*/
use crate::interpreter::{Context, Error};
use crate::interpreter::Context;
use crate::jets::util::*;
use crate::jets::{JetErr, Result};
use crate::jets::Result;
use crate::noun::{IndirectAtom, Noun, D};
use std::cmp;
@ -196,7 +196,7 @@ pub fn jet_rev(context: &mut Context, subject: Noun) -> Result {
let boz = slot(arg, 2)?.as_atom()?.as_direct()?.data();
if boz >= 64 {
return Err(JetErr::Fail(Error::Deterministic(D(0))));
return Err(BAIL_EXIT);
}
let boz = boz as usize;

View File

@ -25,7 +25,7 @@ pub fn jet_zing(context: &mut Context, subject: Noun) -> Result {
}
pub mod util {
use crate::interpreter::Error;
use crate::jets::util::BAIL_EXIT;
use crate::jets::{JetErr, Result};
use crate::mem::NockStack;
use crate::noun::{Cell, Noun, D, T};
@ -56,7 +56,7 @@ pub mod util {
if atom.as_bitslice().first_one().is_none() {
break;
} else {
return Err(JetErr::Fail(Error::Deterministic(D(0))));
return Err(BAIL_EXIT);
}
}
let cell = list.as_cell()?;
@ -98,9 +98,8 @@ pub mod util {
#[cfg(test)]
mod tests {
use super::*;
use crate::interpreter::Error;
use crate::jets::util::test::{assert_jet, assert_jet_err, init_context};
use crate::jets::JetErr;
use crate::jets::util::BAIL_EXIT;
use crate::noun::{D, T};
#[test]
@ -135,9 +134,9 @@ mod tests {
);
assert_jet(c, jet_flop, sam, res);
assert_jet_err(c, jet_flop, D(1), JetErr::Fail(Error::Deterministic(D(0))));
assert_jet_err(c, jet_flop, D(1), BAIL_EXIT);
let sam = T(&mut c.stack, &[D(1), D(2), D(3)]);
assert_jet_err(c, jet_flop, sam, JetErr::Fail(Error::Deterministic(D(0))));
assert_jet_err(c, jet_flop, sam, BAIL_EXIT);
}
#[test]
@ -149,9 +148,9 @@ mod tests {
assert_jet(c, jet_lent, sam, D(3));
let sam = T(&mut c.stack, &[D(3), D(2), D(1), D(0)]);
assert_jet(c, jet_lent, sam, D(3));
assert_jet_err(c, jet_lent, D(1), JetErr::Fail(Error::Deterministic(D(0))));
assert_jet_err(c, jet_lent, D(1), BAIL_EXIT);
let sam = T(&mut c.stack, &[D(3), D(2), D(1)]);
assert_jet_err(c, jet_lent, sam, JetErr::Fail(Error::Deterministic(D(0))));
assert_jet_err(c, jet_lent, sam, BAIL_EXIT);
}
#[test]

View File

@ -114,9 +114,9 @@ pub fn jet_sivc_de(context: &mut Context, subject: Noun) -> Result {
}
mod util {
use crate::interpreter::Error;
use crate::jets::bits::util::met;
use crate::jets::list;
use crate::jets::util::BAIL_FAIL;
use crate::jets::{JetErr, Result};
use crate::mem::NockStack;
use crate::noun::{Atom, IndirectAtom, Noun, D, T};
@ -219,7 +219,7 @@ mod util {
unsafe {
let txt_len = match len.as_direct() {
Ok(direct) => direct.data() as usize,
Err(_) => return Err(JetErr::Fail(Error::NonDeterministic(D(0)))),
Err(_) => return Err(BAIL_FAIL),
};
let iv_bytes = &mut [0u8; 16];

View File

@ -1,9 +1,9 @@
use crate::interpreter::{Context, Error};
use crate::interpreter::Context;
use crate::jets::bits::util::met;
use crate::jets::util::slot;
use crate::jets::util::{slot, BAIL_EXIT};
use crate::jets::{JetErr, Result};
use crate::mem::NockStack;
use crate::noun::{IndirectAtom, Noun, D, NO, YES};
use crate::noun::{IndirectAtom, Noun, NO, YES};
use ares_crypto::ed25519::{ac_ed_puck, ac_ed_shar, ac_ed_sign, ac_ed_veri};
crate::gdb!();
@ -14,7 +14,7 @@ pub fn jet_puck(context: &mut Context, subject: Noun) -> Result {
let sed_len = met(3, sed);
if sed_len > 32 {
return Err(JetErr::Fail(Error::Deterministic(D(0))));
return Err(BAIL_EXIT);
}
unsafe {
@ -35,7 +35,7 @@ pub fn jet_shar(context: &mut Context, subject: Noun) -> Result {
if met(3, sec_key) > 32 {
// sek is size checked by +puck via +suck
return Err(JetErr::Fail(Error::Deterministic(D(0))));
return Err(BAIL_EXIT);
}
if met(3, pub_key) > 32 {
// pub is not size checked in Hoon, but it must be 32 bytes or less for
@ -69,7 +69,7 @@ pub fn jet_sign(context: &mut Context, subject: Noun) -> Result {
let sed_bytes = sed.as_bytes();
let sed_len = sed_bytes.len();
if sed_len > 32 {
return Err(JetErr::Fail(Error::Deterministic(D(0))));
return Err(BAIL_EXIT);
};
let seed = &mut [0u8; 32];
seed[0..sed_len].copy_from_slice(sed_bytes);
@ -81,8 +81,7 @@ pub fn jet_sign(context: &mut Context, subject: Noun) -> Result {
let (_msg_ida, message) = IndirectAtom::new_raw_mut_bytes(stack, msg_len);
message.copy_from_slice(&msg.as_bytes()[0..msg_len]);
ac_ed_sign(message, seed, sig);
}
else {
} else {
ac_ed_sign(&[0u8; 0], seed, sig);
}
@ -132,10 +131,7 @@ mod tests {
fn test_puck() {
let c = &mut init_context();
let sam = A(
&mut c.stack,
&ubig!(_0x0),
);
let sam = A(&mut c.stack, &ubig!(_0x0));
let ret = A(
&mut c.stack,
&ubig!(_0x29da598ba148c03aa643e21d77153265730d6f2ad0a8a3622da4b6cebc276a3b),
@ -158,10 +154,7 @@ mod tests {
let c = &mut init_context();
let sam = T(&mut c.stack, &[D(0), D(0)]);
let ret = A(
&mut c.stack,
&ubig!(_0x0),
);
let ret = A(&mut c.stack, &ubig!(_0x0));
assert_jet(c, jet_shar, sam, ret);
let sam = T(&mut c.stack, &[D(234), D(234)]);
@ -175,7 +168,7 @@ mod tests {
&mut c.stack,
&ubig!(_0xfb099b0acc4d1ce37f9982a2ed331245e0cdfdf6979364b7676a142b8233e53b),
);
assert_jet_err(c, jet_shar, sam, JetErr::Fail(Error::Deterministic(D(0))));
assert_jet_err(c, jet_shar, sam, BAIL_EXIT);
}
#[test]

View File

@ -1,8 +1,8 @@
use crate::interpreter::{Context, Error};
use crate::interpreter::Context;
use crate::jets::bits::util::met;
use crate::jets::util::slot;
use crate::jets::{JetErr, Result};
use crate::noun::{IndirectAtom, Noun, D};
use crate::jets::util::{slot, BAIL_FAIL};
use crate::jets::Result;
use crate::noun::{IndirectAtom, Noun};
use ares_crypto::sha::{ac_sha1, ac_shal, ac_shas, ac_shay};
crate::gdb!();
@ -25,14 +25,12 @@ pub fn jet_shas(context: &mut Context, subject: Noun) -> Result {
let (_msg_ida, message) = IndirectAtom::new_raw_mut_bytes(stack, msg_len);
message.copy_from_slice(&ruz.as_bytes()[0..msg_len]);
ac_shas(message, salt, out);
}
else {
} else {
ac_shas(&mut [], salt, out);
}
Ok(out_ida.normalize_as_atom().as_noun())
}
}
pub fn jet_shax(context: &mut Context, subject: Noun) -> Result {
@ -48,8 +46,7 @@ pub fn jet_shax(context: &mut Context, subject: Noun) -> Result {
let (mut _msg_ida, msg_copy) = IndirectAtom::new_raw_mut_bytes(stack, len);
msg_copy.copy_from_slice(&msg.as_bytes()[0..len]);
ac_shay(&mut (msg_copy)[0..len], out);
}
else {
} else {
ac_shay(&mut [], out);
}
@ -65,7 +62,7 @@ pub fn jet_shay(context: &mut Context, subject: Noun) -> Result {
let width = match wid.as_direct() {
Ok(direct) => direct.data() as usize,
Err(_) => return Err(JetErr::Fail(Error::NonDeterministic(D(0)))),
Err(_) => return Err(BAIL_FAIL),
};
unsafe {
@ -74,8 +71,7 @@ pub fn jet_shay(context: &mut Context, subject: Noun) -> Result {
let (mut _msg_ida, msg) = IndirectAtom::new_raw_mut_bytes(stack, width);
msg.copy_from_slice(&dat.as_bytes()[0..width]);
ac_shay(msg, out);
}
else {
} else {
ac_shay(&mut [], out);
}
Ok(out_ida.normalize_as_atom().as_noun())
@ -90,7 +86,7 @@ pub fn jet_shal(context: &mut Context, subject: Noun) -> Result {
let _width = match wid.as_direct() {
Ok(direct) => direct.data() as usize,
Err(_) => return Err(JetErr::Fail(Error::NonDeterministic(D(0)))),
Err(_) => return Err(BAIL_FAIL),
};
let msg_len = met(3, dat);
@ -101,8 +97,7 @@ pub fn jet_shal(context: &mut Context, subject: Noun) -> Result {
let (mut _msg_ida, msg) = IndirectAtom::new_raw_mut_bytes(stack, msg_len);
msg.copy_from_slice(&dat.as_bytes()[0..msg_len]);
ac_shal(msg, out);
}
else {
} else {
ac_shal(&mut [], out);
}
Ok(ida.normalize_as_atom().as_noun())
@ -117,7 +112,7 @@ pub fn jet_sha1(context: &mut Context, subject: Noun) -> Result {
let width = match wid.as_direct() {
Ok(direct) => direct.data() as usize,
Err(_) => return Err(JetErr::Fail(Error::NonDeterministic(D(0)))),
Err(_) => return Err(BAIL_FAIL),
};
unsafe {
@ -276,24 +271,14 @@ mod tests {
IndirectAtom::new_raw_bytes(&mut c.stack, 8, &big as *const u64 as *const u8)
};
let sam = T(&mut c.stack, &[ida.as_noun(), D(478560413032)]);
assert_jet_err(
c,
jet_shay,
sam,
JetErr::Fail(Error::NonDeterministic(D(0))),
);
assert_jet_err(c, jet_shay, sam, BAIL_FAIL);
let big: u128 = (DIRECT_MAX as u128) << 64;
let ida = unsafe {
IndirectAtom::new_raw_bytes(&mut c.stack, 8, &big as *const u128 as *const u8)
};
let sam = T(&mut c.stack, &[ida.as_noun(), D(478560413032)]);
assert_jet_err(
c,
jet_shay,
sam,
JetErr::Fail(Error::NonDeterministic(D(0))),
);
assert_jet_err(c, jet_shay, sam, BAIL_FAIL);
}
#[test]
@ -333,24 +318,14 @@ mod tests {
&ubig!(_0xa1d6eb6ef33f233ae6980ca7c4fc65f90fe1bdee11c730d41607b4747c83de73),
);
let sam = T(&mut c.stack, &[wid, dat]);
assert_jet_err(
c,
jet_shal,
sam,
JetErr::Fail(Error::NonDeterministic(D(0))),
);
assert_jet_err(c, jet_shal, sam, BAIL_FAIL);
let wid = A(
&mut c.stack,
&ubig!(_0xa1d6eb6ef33f233ae6980ca7c4fc65f90fe1bdee11c730d41607b4747c83de72),
);
let sam = T(&mut c.stack, &[wid, D(1)]);
assert_jet_err(
c,
jet_shal,
sam,
JetErr::Fail(Error::NonDeterministic(D(0))),
);
assert_jet_err(c, jet_shal, sam, BAIL_FAIL);
}
#[test]
@ -382,23 +357,13 @@ mod tests {
&ubig!(_0xa1d6eb6ef33f233ae6980ca7c4fc65f90fe1bdee11c730d41607b4747c83de73),
);
let sam = T(&mut c.stack, &[wid, dat]);
assert_jet_err(
c,
jet_sha1,
sam,
JetErr::Fail(Error::NonDeterministic(D(0))),
);
assert_jet_err(c, jet_sha1, sam, BAIL_FAIL);
let wid = A(
&mut c.stack,
&ubig!(_0xa1d6eb6ef33f233ae6980ca7c4fc65f90fe1bdee11c730d41607b4747c83de72),
);
let sam = T(&mut c.stack, &[wid, D(1)]);
assert_jet_err(
c,
jet_sha1,
sam,
JetErr::Fail(Error::NonDeterministic(D(0))),
);
assert_jet_err(c, jet_sha1, sam, BAIL_FAIL);
}
}

View File

@ -12,9 +12,9 @@
* Another approach is use a global custom allocator. This is fairly involved, but it would allow
* us to use any library without worrying whether it allocates.
*/
use crate::interpreter::{Context, Error};
use crate::interpreter::Context;
use crate::jets::util::*;
use crate::jets::{JetErr, Result};
use crate::jets::Result;
use crate::noun::{Atom, DirectAtom, IndirectAtom, Noun, D, DIRECT_MAX, NO, T, YES};
use either::{Left, Right};
use ibig::ops::DivRem;
@ -35,7 +35,7 @@ pub fn jet_dec(context: &mut Context, subject: Noun) -> Result {
match atom.as_either() {
Left(direct) => {
if direct.data() == 0 {
Err(JetErr::Fail(Error::Deterministic(D(0))))
Err(BAIL_EXIT)
} else {
Ok(unsafe { DirectAtom::new_unchecked(direct.data() - 1) }.as_noun())
}
@ -63,7 +63,7 @@ pub fn jet_dec(context: &mut Context, subject: Noun) -> Result {
}
}
} else {
Err(JetErr::Fail(Error::Deterministic(D(0))))
Err(BAIL_EXIT)
}
}
@ -74,7 +74,7 @@ pub fn jet_div(context: &mut Context, subject: Noun) -> Result {
let b = slot(arg, 3)?.as_atom()?;
if unsafe { b.as_noun().raw_equals(D(0)) } {
Err(JetErr::Fail(Error::Deterministic(D(0))))
Err(BAIL_EXIT)
} else if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) {
Ok(unsafe { DirectAtom::new_unchecked(a.data() / b.data()) }.as_noun())
} else {
@ -92,7 +92,7 @@ pub fn jet_dvr(context: &mut Context, subject: Noun) -> Result {
let b = slot(arg, 3)?.as_atom()?;
if unsafe { b.as_noun().raw_equals(D(0)) } {
Err(JetErr::Fail(Error::Deterministic(D(0))))
Err(BAIL_EXIT)
} else {
let (div, rem) = if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) {
let (div, rem) = (a.data() / b.data(), a.data() % b.data());
@ -245,7 +245,7 @@ pub fn jet_mod(context: &mut Context, subject: Noun) -> Result {
let b = slot(arg, 3)?.as_atom()?;
if unsafe { b.as_noun().raw_equals(D(0)) } {
Err(JetErr::Fail(Error::Deterministic(D(0))))
Err(BAIL_EXIT)
} else if let (Ok(a), Ok(b)) = (a.as_direct(), b.as_direct()) {
Ok(unsafe { DirectAtom::new_unchecked(a.data() % b.data()) }.as_noun())
} else {
@ -429,7 +429,7 @@ mod tests {
let (a0, _a24, a63, _a96, a128) = atoms(s);
assert_jet_ubig(c, jet_dec, a128, ubig!(0xdeadbeef12345678fedcba987654320f));
assert_jet(c, jet_dec, a63, D(0x7ffffffffffffffe));
assert_jet_err(c, jet_dec, a0, JetErr::Fail(Error::Deterministic(D(0))));
assert_jet_err(c, jet_dec, a0, BAIL_EXIT);
}
#[test]
@ -451,18 +451,8 @@ mod tests {
_0x00000000000001000000000000000000000000000000000000000000000000000000000000000001
);
assert_common_jet(c, jet_div, &[atom_528, atom_264], res);
assert_common_jet_err(
c,
jet_div,
&[atom_63, atom_0],
JetErr::Fail(Error::Deterministic(D(0))),
);
assert_common_jet_err(
c,
jet_div,
&[atom_0, atom_0],
JetErr::Fail(Error::Deterministic(D(0))),
);
assert_common_jet_err(c, jet_div, &[atom_63, atom_0], BAIL_EXIT);
assert_common_jet_err(c, jet_div, &[atom_0, atom_0], BAIL_EXIT);
}
#[test]
@ -508,12 +498,7 @@ mod tests {
let res = T(&mut c.stack, &[res_a, res_b]);
assert_jet(c, jet_dvr, sam, res);
assert_common_jet_err(
c,
jet_dvr,
&[atom_63, atom_0],
JetErr::Fail(Error::Deterministic(D(0))),
);
assert_common_jet_err(c, jet_dvr, &[atom_63, atom_0], BAIL_EXIT);
}
#[test]
@ -675,18 +660,8 @@ mod tests {
assert_common_jet(c, jet_mod, &[atom_63, atom_24], ubig!(0x798385));
assert_common_jet(c, jet_mod, &[atom_128, atom_24], ubig!(0x3b2013));
assert_common_jet(c, jet_mod, &[atom_528, atom_264], ubig!(0x100));
assert_common_jet_err(
c,
jet_mod,
&[atom_63, atom_0],
JetErr::Fail(Error::Deterministic(D(0))),
);
assert_common_jet_err(
c,
jet_mod,
&[atom_0, atom_0],
JetErr::Fail(Error::Deterministic(D(0))),
);
assert_common_jet_err(c, jet_mod, &[atom_63, atom_0], BAIL_EXIT);
assert_common_jet_err(c, jet_mod, &[atom_0, atom_0], BAIL_EXIT);
}
#[test]
@ -732,11 +707,6 @@ mod tests {
);
assert_common_jet(c, jet_sub, &[atom_63, atom_63], ubig!(0));
assert_common_jet(c, jet_sub, &[atom_128, atom_128], ubig!(0));
assert_common_jet_err(
c,
jet_sub,
&[atom_63, atom_96],
JetErr::Fail(Error::Deterministic(D(0))),
);
assert_common_jet_err(c, jet_sub, &[atom_63, atom_96], BAIL_EXIT);
}
}

View File

@ -71,7 +71,7 @@ pub fn jet_mute(context: &mut Context, subject: Noun) -> Result {
pub mod util {
use crate::hamt::Hamt;
use crate::interpreter::{interpret, Context, Error};
use crate::interpreter::{interpret, Context, Error, Mote};
use crate::jets;
use crate::jets::bits::util::rip;
use crate::jets::form::util::scow;
@ -164,7 +164,7 @@ pub mod util {
context.scry_stack = scry_snapshot;
Ok(T(&mut context.stack, &[D(1), path]))
}
Error::Deterministic(trace) => {
Error::Deterministic(_, trace) => {
context.cache = cache_snapshot;
context.scry_stack = scry_snapshot;
Ok(T(&mut context.stack, &[D(2), trace]))
@ -185,12 +185,12 @@ pub mod util {
// are identical, jet_mink() bails with Error::Deterministic. Otherwise, it forwards
// the Error::ScryCrashed to the senior virtualization call.
if unsafe { context.scry_stack.raw_equals(scry_snapshot) } {
Err(Error::Deterministic(trace))
Err(Error::Deterministic(Mote::Exit, trace))
} else {
Err(err)
}
}
Error::NonDeterministic(_) => {
Error::NonDeterministic(_, _) => {
// We choose to restore the cache and scry stack even on NonDeterministic errors
// to keep the logic all in one place (as opposed to having the serf reset them
// manually ONLY for NonDeterministic errors).
@ -212,7 +212,7 @@ pub mod util {
if (tag.data() != 2) | unsafe { original_list.raw_equals(D(0)) } {
return Ok(tone);
} else if original_list.atom().is_some() {
return Err(Error::Deterministic(D(0)));
return Err(Error::Deterministic(Mote::Exit, D(0)));
}
// XX: trim traces longer than 1024 frames

View File

@ -1,9 +1,9 @@
/** Tree jets
*/
use crate::interpreter::{Context, Error};
use crate::interpreter::Context;
use crate::jets::bits::util::*;
use crate::jets::util::*;
use crate::jets::{JetErr, Result};
use crate::jets::Result;
use crate::noun::{IndirectAtom, Noun, D};
crate::gdb!();
@ -15,7 +15,7 @@ pub fn jet_cap(_context: &mut Context, subject: Noun) -> Result {
unsafe {
if met < 2 {
Err(JetErr::Fail(Error::Deterministic(D(0))))
Err(BAIL_EXIT)
} else if *(tom.as_bitslice().get_unchecked(met - 2)) {
Ok(D(3))
} else {
@ -30,7 +30,7 @@ pub fn jet_mas(context: &mut Context, subject: Noun) -> Result {
let met = met(0, tom);
if met < 2 {
Err(JetErr::Fail(Error::Deterministic(D(0))))
Err(BAIL_EXIT)
} else {
let out_bits = met - 1;
let out_words = (out_bits + 63) >> 6;
@ -52,11 +52,11 @@ pub fn jet_peg(context: &mut Context, subject: Noun) -> Result {
unsafe {
if a.as_noun().raw_equals(D(0)) {
return Err(JetErr::Fail(Error::Deterministic(D(0))));
return Err(BAIL_EXIT);
};
if b.as_noun().raw_equals(D(0)) {
return Err(JetErr::Fail(Error::Deterministic(D(0))));
return Err(BAIL_EXIT);
};
}
@ -78,9 +78,7 @@ pub fn jet_peg(context: &mut Context, subject: Noun) -> Result {
#[cfg(test)]
mod tests {
use super::*;
use crate::interpreter::Error;
use crate::jets::util::test::*;
use crate::jets::JetErr;
use crate::mem::NockStack;
use crate::noun::{Noun, D, DIRECT_MAX};
use ibig::ubig;
@ -129,8 +127,8 @@ mod tests {
fn test_cap() {
let c = &mut init_context();
assert_jet_err(c, jet_cap, D(0), JetErr::Fail(Error::Deterministic(D(0))));
assert_jet_err(c, jet_cap, D(1), JetErr::Fail(Error::Deterministic(D(0))));
assert_jet_err(c, jet_cap, D(0), BAIL_EXIT);
assert_jet_err(c, jet_cap, D(1), BAIL_EXIT);
assert_jet(c, jet_cap, D(2), D(2));
assert_jet(c, jet_cap, D(3), D(3));
@ -150,8 +148,8 @@ mod tests {
let a66 = atom_66(&mut c.stack);
// Test invalid input
assert_jet_err(c, jet_mas, D(0), JetErr::Fail(Error::Deterministic(D(0))));
assert_jet_err(c, jet_mas, D(1), JetErr::Fail(Error::Deterministic(D(0))));
assert_jet_err(c, jet_mas, D(0), BAIL_EXIT);
assert_jet_err(c, jet_mas, D(1), BAIL_EXIT);
// Test direct
assert_jet(c, jet_mas, D(2), D(1));
@ -177,18 +175,8 @@ mod tests {
fn test_peg() {
let c = &mut init_context();
assert_common_jet_err(
c,
jet_peg,
&[atom_0, atom_1],
JetErr::Fail(Error::Deterministic(D(0))),
);
assert_common_jet_err(
c,
jet_peg,
&[atom_1, atom_0],
JetErr::Fail(Error::Deterministic(D(0))),
);
assert_common_jet_err(c, jet_peg, &[atom_0, atom_1], BAIL_EXIT);
assert_common_jet_err(c, jet_peg, &[atom_1, atom_0], BAIL_EXIT);
// Test direct
assert_common_jet_noun(c, jet_peg, &[pos_2, pos_3], D(5));

View File

@ -1,6 +1,6 @@
use crate::hamt::Hamt;
use crate::interpreter;
use crate::interpreter::{inc, interpret, Error};
use crate::interpreter::{inc, interpret, Error, Mote};
use crate::jets::cold::Cold;
use crate::jets::hot::{Hot, HotEntry};
use crate::jets::list::util::{lent, zing};
@ -418,7 +418,7 @@ fn peek(context: &mut Context, ovo: Noun) -> Noun {
}
}
fn goof(context: &mut Context, traces: Noun) -> Noun {
fn goof(context: &mut Context, mote: Mote, traces: Noun) -> Noun {
let trace = zing(&mut context.nock_context.stack, traces).unwrap();
let tone = Cell::new(&mut context.nock_context.stack, D(2), trace);
let tang = mook(&mut context.nock_context, tone, false)
@ -427,7 +427,7 @@ fn goof(context: &mut Context, traces: Noun) -> Noun {
// XX: noun::Error should use a bail enum system similar to u3m_bail motes;
// might be able to replace NockErr with mote and map determinism to individual motes;
// for, always set to %exit
T(&mut context.nock_context.stack, &[D(tas!(b"exit")), tang])
T(&mut context.nock_context.stack, &[D(mote as u64), tang])
}
/** Run slam; process stack trace to tang if error.
@ -451,8 +451,8 @@ fn soft(context: &mut Context, ovo: Noun, trace_name: Option<String>) -> Result<
match slam_res {
Ok(res) => Ok(res),
Err(error) => match error {
Error::Deterministic(trace) | Error::NonDeterministic(trace) => {
Err(goof(context, trace))
Error::Deterministic(mote, trace) | Error::NonDeterministic(mote, trace) => {
Err(goof(context, mote, trace))
}
Error::ScryBlocked(_) | Error::ScryCrashed(_) => {
panic!("serf: soft: .^ invalid outside of virtual Nock")
@ -488,8 +488,8 @@ fn play_life(context: &mut Context, eve: Noun) {
context.play_done();
}
Err(error) => match error {
Error::Deterministic(trace) | Error::NonDeterministic(trace) => {
let goof = goof(context, trace);
Error::Deterministic(mote, trace) | Error::NonDeterministic(mote, trace) => {
let goof = goof(context, mote, trace);
context.play_bail(goof);
}
Error::ScryBlocked(_) | Error::ScryCrashed(_) => {

View File

@ -27,7 +27,7 @@ guard_err _focus_guard()
// Check for strange situations.
if (stack_p == 0 || alloc_p == 0) {
fprintf(stderr, "guard: stack or alloc pointer is null\r\n");
// fprintf(stderr, "guard: stack or alloc pointer is null\r\n");
return guard_weird;
}
@ -46,7 +46,7 @@ guard_err _focus_guard()
guard_p = stack_p + ((alloc_p - stack_p) / 2);
}
else {
fprintf(stderr, "guard: weird; stack and alloc pointers are equal\r\n");
// fprintf(stderr, "guard: weird; stack and alloc pointers are equal\r\n");
return guard_weird;
}
guard_p = (void *)((uintptr_t)guard_p & ~(GD_PAGESIZE - 1));
@ -60,14 +60,14 @@ guard_err _focus_guard()
return guard_spent;
}
fprintf(stderr, "guard: installed guard page at %p\r\n", (void *) guard_p);
// fprintf(stderr, "guard: installed guard page at %p\r\n", (void *) guard_p);
return guard_sound;
}
guard_err _slash_guard(void *si_addr) {
if (si_addr >= (void *)guard_p && si_addr < (void *)guard_p + GD_PAGESIZE) {
fprintf(stderr, "guard: slash in guard\r\n");
// fprintf(stderr, "guard: slash in guard\r\n");
return _focus_guard();
}
@ -78,11 +78,11 @@ void _signal_handler(int sig, siginfo_t *si, void *unused)
{
switch (sig) {
case SIGSEGV:
fprintf(stderr, "guard: sigsegv at %p\r\n", si->si_addr);
// fprintf(stderr, "guard: sigsegv at %p\r\n", si->si_addr);
err = _slash_guard(si->si_addr);
break;
case SIGINT:
fprintf(stderr, "guard: sigint\r\n");
// fprintf(stderr, "guard: sigint\r\n");
err = guard_erupt;
break;
default:
@ -90,7 +90,7 @@ void _signal_handler(int sig, siginfo_t *si, void *unused)
}
if (err != guard_sound) {
fprintf(stderr, "guard: error %d; long jumping\r\n", err);
// fprintf(stderr, "guard: error %d; long jumping\r\n", err);
longjmp(env_buffer, 1);
}
}
@ -102,7 +102,8 @@ guard_err _register_handler() {
sa.sa_sigaction = _signal_handler;
sa.sa_mask = 0;
if (sigaction(SIGSEGV, &sa, 0) || sigaction(SIGINT, &sa, 0)) {
// if (sigaction(SIGSEGV, &sa, 0) || sigaction(SIGINT, &sa, 0)) {
if (sigaction(SIGSEGV, &sa, 0)) {
return guard_weird;
}
@ -127,7 +128,7 @@ guard_err guard(
if (guard_p == 0) {
guard_err install_err = _focus_guard();
if (install_err != guard_sound) {
fprintf(stderr, "guard: failed to install guard page\r\n");
// fprintf(stderr, "guard: failed to install guard page\r\n");
err = install_err;
goto fail;
}
@ -160,21 +161,21 @@ guard_err guard(
fail:
if (mprotect(guard_p, GD_PAGESIZE, PROT_READ | PROT_WRITE) == -1) {
fprintf(stderr, "guard: failed to uninstall guard page\r\n");
// fprintf(stderr, "guard: failed to uninstall guard page\r\n");
}
fprintf(stderr, "guard: fail; uninstalled guard page\r\n");
// fprintf(stderr, "guard: fail; uninstalled guard page\r\n");
switch (err) {
case guard_armor:
fprintf(stderr, "guard: armor error\r\n");
// fprintf(stderr, "guard: armor error\r\n");
break;
case guard_weird:
fprintf(stderr, "guard: weird error\r\n");
// fprintf(stderr, "guard: weird error\r\n");
break;
case guard_spent:
fprintf(stderr, "guard: spent error\r\n");
// fprintf(stderr, "guard: spent error\r\n");
break;
case guard_erupt:
fprintf(stderr, "guard: erupt error\r\n");
// fprintf(stderr, "guard: erupt error\r\n");
break;
}
return err;