Fix zero-arg builtins invokations.
There are currently two zero-arg builtins: - mkNilData - mkNilPairData And while they have strictly speaking no arguments, the VM still requires that they are called with an extra unit argument applied.
This commit is contained in:
parent
1c58da4d86
commit
643e43f8aa
|
@ -4066,10 +4066,16 @@ impl<'a> CodeGenerator<'a> {
|
||||||
builtin,
|
builtin,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
assert!(
|
if let Some(func) = builtin {
|
||||||
builtin.is_none(),
|
return self.gen_uplc(
|
||||||
"found remaining builtin function {func_name:?} ({builtin:?} declared as a module function in {module:?}"
|
Air::Builtin {
|
||||||
|
count: 0,
|
||||||
|
func: *func,
|
||||||
|
tipo: constructor.tipo,
|
||||||
|
},
|
||||||
|
arg_stack,
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if let Some((names, index, cyclic_name)) = self.cyclic_functions.get(&(
|
if let Some((names, index, cyclic_name)) = self.cyclic_functions.get(&(
|
||||||
FunctionAccessKey {
|
FunctionAccessKey {
|
||||||
|
@ -4490,9 +4496,13 @@ impl<'a> CodeGenerator<'a> {
|
||||||
|
|
||||||
term = builder::apply_builtin_forces(term, func.force_count());
|
term = builder::apply_builtin_forces(term, func.force_count());
|
||||||
|
|
||||||
|
if func.arg_is_unit() {
|
||||||
|
term = term.apply(Term::unit())
|
||||||
|
} else {
|
||||||
for arg in arg_vec {
|
for arg in arg_vec {
|
||||||
term = term.apply(arg.clone());
|
term = term.apply(arg.clone());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
term
|
term
|
||||||
}
|
}
|
||||||
|
|
|
@ -6562,3 +6562,41 @@ fn mk_cons_direct_invoke_3() {
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn mk_nil_pair_data() {
|
||||||
|
let src = r#"
|
||||||
|
use aiken/builtin.{mk_nil_pair_data}
|
||||||
|
|
||||||
|
test nil_equals() {
|
||||||
|
mk_nil_pair_data() == mk_nil_pair_data()
|
||||||
|
}
|
||||||
|
"#;
|
||||||
|
|
||||||
|
assert_uplc(
|
||||||
|
src,
|
||||||
|
Term::equals_data()
|
||||||
|
.apply(Term::map_data().apply(Term::mk_nil_pair_data().apply(Term::unit())))
|
||||||
|
.apply(Term::map_data().apply(Term::mk_nil_pair_data().apply(Term::unit()))),
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn mk_nil_list_data() {
|
||||||
|
let src = r#"
|
||||||
|
use aiken/builtin.{mk_nil_data}
|
||||||
|
|
||||||
|
test nil_equals() {
|
||||||
|
mk_nil_data() == mk_nil_data()
|
||||||
|
}
|
||||||
|
"#;
|
||||||
|
|
||||||
|
assert_uplc(
|
||||||
|
src,
|
||||||
|
Term::equals_data()
|
||||||
|
.apply(Term::list_data().apply(Term::mk_nil_data().apply(Term::unit())))
|
||||||
|
.apply(Term::list_data().apply(Term::mk_nil_data().apply(Term::unit()))),
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -1,23 +1,20 @@
|
||||||
use std::{mem::size_of, ops::Deref, rc::Rc};
|
use super::{
|
||||||
|
cost_model::{BuiltinCosts, ExBudget},
|
||||||
use num_bigint::BigInt;
|
value::{from_pallas_bigint, to_pallas_bigint},
|
||||||
use num_integer::Integer;
|
Error, Value,
|
||||||
use num_traits::{Signed, Zero};
|
};
|
||||||
use once_cell::sync::Lazy;
|
|
||||||
use pallas_primitives::conway::{Language, PlutusData};
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{Constant, Data, Type},
|
ast::{Constant, Data, Type},
|
||||||
builtins::DefaultFunction,
|
builtins::DefaultFunction,
|
||||||
machine::value::integer_log2,
|
machine::value::integer_log2,
|
||||||
plutus_data_to_bytes,
|
plutus_data_to_bytes,
|
||||||
};
|
};
|
||||||
|
use num_bigint::BigInt;
|
||||||
use super::{
|
use num_integer::Integer;
|
||||||
cost_model::{BuiltinCosts, ExBudget},
|
use num_traits::{Signed, Zero};
|
||||||
value::{from_pallas_bigint, to_pallas_bigint},
|
use once_cell::sync::Lazy;
|
||||||
Error, Value,
|
use pallas_primitives::conway::{Language, PlutusData};
|
||||||
};
|
use std::{mem::size_of, ops::Deref, rc::Rc};
|
||||||
|
|
||||||
static SCALAR_PERIOD: Lazy<BigInt> = Lazy::new(|| {
|
static SCALAR_PERIOD: Lazy<BigInt> = Lazy::new(|| {
|
||||||
BigInt::from_bytes_be(
|
BigInt::from_bytes_be(
|
||||||
|
@ -111,6 +108,85 @@ impl From<DefaultFunction> for BuiltinRuntime {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DefaultFunction {
|
impl DefaultFunction {
|
||||||
|
pub fn arg_is_unit(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
DefaultFunction::MkNilData | DefaultFunction::MkNilPairData => true,
|
||||||
|
DefaultFunction::AddInteger
|
||||||
|
| DefaultFunction::SubtractInteger
|
||||||
|
| DefaultFunction::MultiplyInteger
|
||||||
|
| DefaultFunction::DivideInteger
|
||||||
|
| DefaultFunction::QuotientInteger
|
||||||
|
| DefaultFunction::RemainderInteger
|
||||||
|
| DefaultFunction::ModInteger
|
||||||
|
| DefaultFunction::EqualsInteger
|
||||||
|
| DefaultFunction::LessThanInteger
|
||||||
|
| DefaultFunction::LessThanEqualsInteger
|
||||||
|
| DefaultFunction::AppendByteString
|
||||||
|
| DefaultFunction::ConsByteString
|
||||||
|
| DefaultFunction::SliceByteString
|
||||||
|
| DefaultFunction::LengthOfByteString
|
||||||
|
| DefaultFunction::IndexByteString
|
||||||
|
| DefaultFunction::EqualsByteString
|
||||||
|
| DefaultFunction::LessThanByteString
|
||||||
|
| DefaultFunction::LessThanEqualsByteString
|
||||||
|
| DefaultFunction::Sha2_256
|
||||||
|
| DefaultFunction::Sha3_256
|
||||||
|
| DefaultFunction::Blake2b_224
|
||||||
|
| DefaultFunction::Blake2b_256
|
||||||
|
| DefaultFunction::Keccak_256
|
||||||
|
| DefaultFunction::VerifyEd25519Signature
|
||||||
|
| DefaultFunction::VerifyEcdsaSecp256k1Signature
|
||||||
|
| DefaultFunction::VerifySchnorrSecp256k1Signature
|
||||||
|
| DefaultFunction::AppendString
|
||||||
|
| DefaultFunction::EqualsString
|
||||||
|
| DefaultFunction::EncodeUtf8
|
||||||
|
| DefaultFunction::DecodeUtf8
|
||||||
|
| DefaultFunction::IfThenElse
|
||||||
|
| DefaultFunction::ChooseUnit
|
||||||
|
| DefaultFunction::Trace
|
||||||
|
| DefaultFunction::FstPair
|
||||||
|
| DefaultFunction::SndPair
|
||||||
|
| DefaultFunction::ChooseList
|
||||||
|
| DefaultFunction::MkCons
|
||||||
|
| DefaultFunction::HeadList
|
||||||
|
| DefaultFunction::TailList
|
||||||
|
| DefaultFunction::NullList
|
||||||
|
| DefaultFunction::ChooseData
|
||||||
|
| DefaultFunction::ConstrData
|
||||||
|
| DefaultFunction::MapData
|
||||||
|
| DefaultFunction::ListData
|
||||||
|
| DefaultFunction::IData
|
||||||
|
| DefaultFunction::BData
|
||||||
|
| DefaultFunction::UnConstrData
|
||||||
|
| DefaultFunction::UnMapData
|
||||||
|
| DefaultFunction::UnListData
|
||||||
|
| DefaultFunction::UnIData
|
||||||
|
| DefaultFunction::UnBData
|
||||||
|
| DefaultFunction::EqualsData
|
||||||
|
| DefaultFunction::SerialiseData
|
||||||
|
| DefaultFunction::MkPairData
|
||||||
|
| DefaultFunction::Bls12_381_G1_Add
|
||||||
|
| DefaultFunction::Bls12_381_G1_Neg
|
||||||
|
| DefaultFunction::Bls12_381_G1_ScalarMul
|
||||||
|
| DefaultFunction::Bls12_381_G1_Equal
|
||||||
|
| DefaultFunction::Bls12_381_G1_Compress
|
||||||
|
| DefaultFunction::Bls12_381_G1_Uncompress
|
||||||
|
| DefaultFunction::Bls12_381_G1_HashToGroup
|
||||||
|
| DefaultFunction::Bls12_381_G2_Add
|
||||||
|
| DefaultFunction::Bls12_381_G2_Neg
|
||||||
|
| DefaultFunction::Bls12_381_G2_ScalarMul
|
||||||
|
| DefaultFunction::Bls12_381_G2_Equal
|
||||||
|
| DefaultFunction::Bls12_381_G2_Compress
|
||||||
|
| DefaultFunction::Bls12_381_G2_Uncompress
|
||||||
|
| DefaultFunction::Bls12_381_G2_HashToGroup
|
||||||
|
| DefaultFunction::Bls12_381_MillerLoop
|
||||||
|
| DefaultFunction::Bls12_381_MulMlResult
|
||||||
|
| DefaultFunction::Bls12_381_FinalVerify
|
||||||
|
| DefaultFunction::IntegerToByteString
|
||||||
|
| DefaultFunction::ByteStringToInteger => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn arity(&self) -> usize {
|
pub fn arity(&self) -> usize {
|
||||||
match self {
|
match self {
|
||||||
DefaultFunction::AddInteger => 2,
|
DefaultFunction::AddInteger => 2,
|
||||||
|
|
Loading…
Reference in New Issue