fix(vm): make sure that we only jump to jump targets
This commit is contained in:
parent
14e809e0a6
commit
94117e5817
|
@ -2,7 +2,7 @@ use crate::consts::{AtomOp, MathBinOp, OpType};
|
|||
use crate::{Atom, Value};
|
||||
use core::fmt;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum Instr<'a> {
|
||||
// control flow
|
||||
/// defines a destination label
|
||||
|
|
|
@ -11,19 +11,30 @@ struct Module {
|
|||
type InstrPtr = (Arc<Module>, usize);
|
||||
|
||||
trait Origin: Send + Sync + core::fmt::Debug {
|
||||
fn call(&self, instrp: &mut InstrPtr, p: &Pointer, a: &Atom);
|
||||
fn call(&self, p: &Pointer, a: &Atom) -> InstrPtr;
|
||||
fn incr_refcount(&self, p: &Pointer);
|
||||
fn decr_refcount(&self, p: &Pointer);
|
||||
}
|
||||
|
||||
static NOOP_MODULE: Lazy<Arc<Module>> = Lazy::new(|| {
|
||||
let mut v = Vec::new();
|
||||
use fogtix_bytecode::Instr;
|
||||
Instr::Label.write_to(&mut v).unwrap();
|
||||
Instr::Return.write_to(&mut v).unwrap();
|
||||
Arc::new(Module {
|
||||
h: readfilez::FileHandle::Buffered(v),
|
||||
})
|
||||
});
|
||||
|
||||
#[derive(Debug)]
|
||||
struct NoopOrigin;
|
||||
impl Origin for NoopOrigin {
|
||||
fn call(&self, _instrp: &mut InstrPtr, p: &Pointer, a: &Atom) {
|
||||
fn call(&self, p: &Pointer, a: &Atom) -> InstrPtr {
|
||||
eprintln!(
|
||||
"WARN: tried to invoke pointer {:?}({:?}) without valid context",
|
||||
p, a
|
||||
);
|
||||
(Arc::clone(&NOOP_MODULE), 0)
|
||||
}
|
||||
fn incr_refcount(&self, _p: &Pointer) {}
|
||||
fn decr_refcount(&self, _p: &Pointer) {}
|
||||
|
@ -119,7 +130,7 @@ impl Process {
|
|||
break;
|
||||
}
|
||||
Some(StackEntValue::Pointer(wp)) => {
|
||||
wp.orig.call(&mut self.instrp, &wp.p, &atom);
|
||||
self.instrp = wp.orig.call(&wp.p, &atom);
|
||||
}
|
||||
Some(x) => {
|
||||
eprintln!(
|
||||
|
@ -129,6 +140,17 @@ impl Process {
|
|||
break;
|
||||
}
|
||||
}
|
||||
if let Some(n2xti_arr) = self.instrp.0.h.get(self.instrp.1..) {
|
||||
if let Ok((_, trgi)) = Instr::parse(n2xti_arr) {
|
||||
if trgi != Instr::Label {
|
||||
eprintln!(
|
||||
"ERROR: `call` arrived at non-jump target {:?} @ {}",
|
||||
trgi, previptr
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Instr::Jump(x) => {
|
||||
self.instrp.1 = match x.try_into() {
|
||||
|
@ -140,6 +162,17 @@ impl Process {
|
|||
);
|
||||
break;
|
||||
}
|
||||
};
|
||||
if let Some(n2xti_arr) = self.instrp.0.h.get(self.instrp.1..) {
|
||||
if let Ok((_, trgi)) = Instr::parse(n2xti_arr) {
|
||||
if trgi != Instr::Label {
|
||||
eprintln!(
|
||||
"ERROR: jump arrived at non-jump target {:?} @ {}",
|
||||
trgi, previptr
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Instr::Return => match self.callstack.pop() {
|
||||
|
|
Loading…
Reference in a new issue