feat(machine): reduce term allocations

* remove term from VBuiltin
* and also means we don't need the useless wrapping

Co-authored-by: Lucas Rosa <x@rvcas.dev>
This commit is contained in:
microproofs 2023-04-12 16:09:42 -04:00 committed by Lucas
parent 70f12d3fc5
commit 09a6ea51d6
3 changed files with 33 additions and 46 deletions

View File

@ -1,9 +1,6 @@
use std::rc::Rc;
use crate::{
ast::{Constant, NamedDeBruijn, Term, Type},
builtins::DefaultFunction,
};
use crate::ast::{Constant, NamedDeBruijn, Term, Type};
pub mod cost_model;
mod discharge;
@ -147,11 +144,7 @@ impl Machine {
Ok(MachineState::Return(
context,
Value::Builtin {
fun,
term: term.into(),
runtime,
},
Value::Builtin { fun, runtime },
))
}
}
@ -183,21 +176,21 @@ impl Machine {
Value::Delay(body, env) => {
Ok(MachineState::Compute(context, env, body.as_ref().clone()))
}
Value::Builtin {
fun,
term,
mut runtime,
} => {
let force_term = Term::Force(term);
Value::Builtin { fun, mut runtime } => {
if runtime.needs_force() {
runtime.consume_force();
let res = self.eval_builtin_app(fun, force_term.into(), runtime)?;
let res = if runtime.is_ready() {
self.eval_builtin_app(runtime)?
} else {
Value::Builtin { fun, runtime }
};
Ok(MachineState::Return(context, res))
} else {
Err(Error::BuiltinTermArgumentExpected(force_term))
Err(Error::BuiltinTermArgumentExpected(Term::Constant(
Constant::Unit.into(),
)))
}
}
rest => Err(Error::NonPolymorphicInstantiation(rest)),
@ -222,47 +215,40 @@ impl Machine {
body.as_ref().clone(),
))
}
Value::Builtin { fun, term, runtime } => {
let arg_term = discharge::value_as_term(argument.clone());
let t = Rc::new(Term::<NamedDeBruijn>::Apply {
function: term,
argument: arg_term,
});
Value::Builtin { fun, runtime } => {
// let arg_term = discharge::value_as_term(argument.clone());
if runtime.is_arrow() && !runtime.needs_force() {
let mut runtime = runtime;
runtime.push(argument)?;
let res = self.eval_builtin_app(fun, t, runtime.to_owned())?;
let res = if runtime.is_ready() {
self.eval_builtin_app(runtime)?
} else {
Value::Builtin { fun, runtime }
};
Ok(MachineState::Return(context, res))
} else {
Err(Error::UnexpectedBuiltinTermArgument(t.as_ref().clone()))
Err(Error::UnexpectedBuiltinTermArgument(Term::Constant(
Constant::Unit.into(),
)))
}
}
rest => Err(Error::NonFunctionalApplication(rest, argument)),
}
}
fn eval_builtin_app(
&mut self,
fun: DefaultFunction,
term: Rc<Term<NamedDeBruijn>>,
runtime: BuiltinRuntime,
) -> Result<Value, Error> {
if runtime.is_ready() {
fn eval_builtin_app(&mut self, runtime: BuiltinRuntime) -> Result<Value, Error> {
let cost = match self.version {
Language::PlutusV1 => runtime.to_ex_budget_v1(&self.costs.builtin_costs),
Language::PlutusV2 => runtime.to_ex_budget_v2(&self.costs.builtin_costs),
};
self.spend_budget(cost)?;
runtime.call(&mut self.logs)
} else {
Ok(Value::Builtin { fun, term, runtime })
}
}
fn lookup_var(&mut self, name: &NamedDeBruijn, env: &[Value]) -> Result<Value, Error> {

View File

@ -1,6 +1,6 @@
use std::rc::Rc;
use crate::ast::{NamedDeBruijn, Term};
use crate::ast::{Constant, NamedDeBruijn, Term};
use super::value::{Env, Value};
@ -28,7 +28,9 @@ pub(super) fn value_as_term(value: Value) -> Rc<Term<NamedDeBruijn>> {
match stack_frame {
DischargeStep::DischargeValue(value) => match value {
Value::Con(x) => arg_stack.push(Term::Constant(x.clone()).into()),
Value::Builtin { term, .. } => arg_stack.push(term.clone()),
Value::Builtin { .. } => {
arg_stack.push(Term::Constant(Constant::Unit.into()).into())
}
Value::Delay(body, env) => {
stack.push(DischargeStep::DischargeValueEnv(
0,

View File

@ -24,7 +24,6 @@ pub enum Value {
},
Builtin {
fun: DefaultFunction,
term: Rc<Term<NamedDeBruijn>>,
runtime: BuiltinRuntime,
},
}