Skip to content

Commit

Permalink
feat: add several more builtins needed for benchmarking
Browse files Browse the repository at this point in the history
  • Loading branch information
rvcas committed Oct 8, 2024
1 parent 5811b67 commit 4efdef0
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 8 deletions.
9 changes: 8 additions & 1 deletion crates/uplc/src/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use bumpalo::{
Bump,
};

use crate::{data::PlutusData, typ::Type};
use crate::{data::PlutusData, machine::MachineError, typ::Type};

#[derive(Debug, PartialEq)]
pub enum Constant<'a> {
Expand Down Expand Up @@ -94,4 +94,11 @@ impl<'a> Constant<'a> {
pub fn g2(arena: &'a Bump, g2: &'a blst::blst_p2) -> &'a Constant<'a> {
arena.alloc(Constant::Bls12_381G2Element(g2))
}

pub fn unwrap_data(&'a self) -> Result<&'a PlutusData<'a>, MachineError<'a>> {
match self {
Constant::Data(data) => Ok(data),
_ => Err(MachineError::not_data(self)),
}
}
}
10 changes: 10 additions & 0 deletions crates/uplc/src/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use bumpalo::{collections::Vec as BumpVec, Bump};
use crate::{
constant::{integer_from, Integer},
flat::decode::Ctx,
machine::MachineError,
};

#[derive(Debug, PartialEq)]
Expand Down Expand Up @@ -55,4 +56,13 @@ impl<'a> PlutusData<'a> {
) -> Result<&'a PlutusData<'a>, minicbor::decode::Error> {
minicbor::decode_with(cbor, &mut Ctx { arena })
}

pub fn unwrap_constr(
&'a self,
) -> Result<(&'a u64, &'a BumpVec<&'a PlutusData<'a>>), MachineError<'a>> {
match self {
PlutusData::Constr { tag, fields } => Ok((tag, fields)),
_ => Err(MachineError::malformed_data(self)),
}
}
}
21 changes: 19 additions & 2 deletions crates/uplc/src/flat/data.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use bumpalo::collections::Vec as BumpVec;
use minicbor::data::IanaTag;
use rug::ops::NegAssign;

use crate::data::PlutusData;

Expand Down Expand Up @@ -59,8 +60,24 @@ impl<'a, 'b> minicbor::decode::Decode<'b, Ctx<'a>> for &'a PlutusData<'a> {
}

match tag.try_into() {
Ok(IanaTag::PosBignum | IanaTag::NegBignum) => {
todo!("bignum")
Ok(x @ IanaTag::PosBignum | x @ IanaTag::NegBignum) => {
let mut bytes = BumpVec::new_in(ctx.arena);

for chunk in decoder.bytes_iter()? {
let chunk = chunk?;

bytes.extend_from_slice(chunk);
}

let integer = ctx
.arena
.alloc(rug::Integer::from_digits(&bytes, rug::integer::Order::Msf));

if x == IanaTag::NegBignum {
integer.neg_assign();
}

Ok(PlutusData::integer(ctx.arena, integer))
}

_ => {
Expand Down
12 changes: 12 additions & 0 deletions crates/uplc/src/machine/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use bumpalo::collections::Vec as BumpVec;

use crate::{
constant::{Constant, Integer},
data::PlutusData,
term::Term,
typ::Type,
};
Expand All @@ -16,6 +17,7 @@ pub enum MachineError<'a> {
OpenTermEvaluated(&'a Term<'a>),
OutOfExError(ExBudget),
TypeMismatch(Type<'a>, &'a Constant<'a>),
ExpectedPair(&'a Constant<'a>),
UnexpectedBuiltinTermArgument(&'a Term<'a>),
NonPolymorphicInstantiation(&'a Value<'a>),
BuiltinTermArgumentExpected(&'a Term<'a>),
Expand All @@ -27,6 +29,8 @@ pub enum MachineError<'a> {
#[derive(Debug)]
pub enum RuntimeError<'a> {
ByteStringOutOfBounds(&'a BumpVec<'a, u8>, &'a Integer),
NotData(&'a Constant<'a>),
MalFormedData(&'a PlutusData<'a>),
}

impl<'a> MachineError<'a> {
Expand All @@ -37,4 +41,12 @@ impl<'a> MachineError<'a> {
pub fn byte_string_out_of_bounds(byte_string: &'a BumpVec<'a, u8>, index: &'a Integer) -> Self {
MachineError::runtime(RuntimeError::ByteStringOutOfBounds(byte_string, index))
}

pub fn not_data(constant: &'a Constant<'a>) -> Self {
MachineError::runtime(RuntimeError::NotData(constant))
}

pub fn malformed_data(plutus_data: &'a PlutusData<'a>) -> Self {
MachineError::runtime(RuntimeError::MalFormedData(plutus_data))
}
}
50 changes: 45 additions & 5 deletions crates/uplc/src/machine/runtime.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
use bumpalo::{collections::Vec as BumpVec, Bump};
use bumpalo::{
collections::{CollectIn, Vec as BumpVec},
Bump,
};
use rug::Assign;

use crate::{
builtin::DefaultFunction,
constant::{self},
constant::{self, Constant},
typ::Type,
};

use super::{cost_model::builtin_costs::BuiltinCosts, value::Value, ExBudget, MachineError};
Expand Down Expand Up @@ -243,8 +247,20 @@ impl<'a> Runtime<'a> {
DefaultFunction::DecodeUtf8 => todo!(),
DefaultFunction::ChooseUnit => todo!(),
DefaultFunction::Trace => todo!(),
DefaultFunction::FstPair => todo!(),
DefaultFunction::SndPair => todo!(),
DefaultFunction::FstPair => {
let (_, _, first, _) = self.args[0].unwrap_pair()?;

let value = Value::con(arena, first);

Ok(value)
}
DefaultFunction::SndPair => {
let (_, _, _, second) = self.args[0].unwrap_pair()?;

let value = Value::con(arena, second);

Ok(value)
}
DefaultFunction::ChooseList => todo!(),
DefaultFunction::MkCons => todo!(),
DefaultFunction::HeadList => todo!(),
Expand All @@ -256,7 +272,31 @@ impl<'a> Runtime<'a> {
DefaultFunction::ListData => todo!(),
DefaultFunction::IData => todo!(),
DefaultFunction::BData => todo!(),
DefaultFunction::UnConstrData => todo!(),
DefaultFunction::UnConstrData => {
let arg1 = self.args[0].unwrap_constant()?;
let plutus_data = arg1.unwrap_data()?;

let (tag, fields) = plutus_data.unwrap_constr()?;

let constant = Constant::proto_pair(
arena,
Type::integer(arena),
Type::list(arena, Type::data(arena)),
Constant::integer_from(arena, *tag as i128),
Constant::proto_list(
arena,
Type::data(arena),
fields
.iter()
.map(|d| Constant::data(arena, d))
.collect_in(arena),
),
);

let value = Value::con(arena, constant);

Ok(value)
}
DefaultFunction::UnMapData => todo!(),
DefaultFunction::UnListData => todo!(),
DefaultFunction::UnIData => todo!(),
Expand Down
20 changes: 20 additions & 0 deletions crates/uplc/src/machine/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,26 @@ impl<'a> Value<'a> {
Ok(*b)
}

pub(super) fn unwrap_pair(
&'a self,
) -> Result<
(
&'a Type<'a>,
&'a Type<'a>,
&'a Constant<'a>,
&'a Constant<'a>,
),
MachineError<'a>,
> {
let inner = self.unwrap_constant()?;

let Constant::ProtoPair(t1, t2, first, second) = inner else {
return Err(MachineError::ExpectedPair(inner));
};

Ok((t1, t2, first, second))
}

pub fn unwrap_constant(&'a self) -> Result<&'a Constant<'a>, MachineError<'a>> {
let Value::Con(item) = self else {
return Err(MachineError::NotAConstant(self));
Expand Down

0 comments on commit 4efdef0

Please sign in to comment.