Merge pull request #3042 from dcnorris/numerics
library(numerics), special funs from crate puruspe
This commit is contained in:
@@ -4691,6 +4691,102 @@ impl Machine {
|
||||
self.crypto_data_decrypt();
|
||||
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
||||
}
|
||||
&Instruction::CallBeta => {
|
||||
self.beta();
|
||||
step_or_fail!(self, self.machine_st.p += 1);
|
||||
}
|
||||
&Instruction::ExecuteBeta => {
|
||||
self.beta();
|
||||
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
||||
}
|
||||
&Instruction::CallBetaI => {
|
||||
self.betai();
|
||||
step_or_fail!(self, self.machine_st.p += 1);
|
||||
}
|
||||
&Instruction::ExecuteBetaI => {
|
||||
self.betai();
|
||||
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
||||
}
|
||||
&Instruction::CallInvBetaI => {
|
||||
self.invbetai();
|
||||
step_or_fail!(self, self.machine_st.p += 1);
|
||||
}
|
||||
&Instruction::ExecuteInvBetaI => {
|
||||
self.invbetai();
|
||||
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
||||
}
|
||||
&Instruction::CallGamma => {
|
||||
self.gamma();
|
||||
step_or_fail!(self, self.machine_st.p += 1);
|
||||
}
|
||||
&Instruction::ExecuteGamma => {
|
||||
self.gamma();
|
||||
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
||||
}
|
||||
&Instruction::CallLnGamma => {
|
||||
self.ln_gamma();
|
||||
step_or_fail!(self, self.machine_st.p += 1);
|
||||
}
|
||||
&Instruction::ExecuteLnGamma => {
|
||||
self.ln_gamma();
|
||||
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
||||
}
|
||||
&Instruction::CallGammP => {
|
||||
self.gammp();
|
||||
step_or_fail!(self, self.machine_st.p += 1);
|
||||
}
|
||||
&Instruction::ExecuteGammP => {
|
||||
self.gammp();
|
||||
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
||||
}
|
||||
&Instruction::CallInvGammP => {
|
||||
self.invgammp();
|
||||
step_or_fail!(self, self.machine_st.p += 1);
|
||||
}
|
||||
&Instruction::ExecuteInvGammP => {
|
||||
self.invgammp();
|
||||
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
||||
}
|
||||
&Instruction::CallGammQ => {
|
||||
self.gammq();
|
||||
step_or_fail!(self, self.machine_st.p += 1);
|
||||
}
|
||||
&Instruction::ExecuteGammQ => {
|
||||
self.gammq();
|
||||
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
||||
}
|
||||
&Instruction::CallErf => {
|
||||
self.erf();
|
||||
step_or_fail!(self, self.machine_st.p += 1);
|
||||
}
|
||||
&Instruction::ExecuteErf => {
|
||||
self.erf();
|
||||
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
||||
}
|
||||
&Instruction::CallErfc => {
|
||||
self.erfc();
|
||||
step_or_fail!(self, self.machine_st.p += 1);
|
||||
}
|
||||
&Instruction::ExecuteErfc => {
|
||||
self.erfc();
|
||||
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
||||
}
|
||||
&Instruction::CallInvErf => {
|
||||
self.inverf();
|
||||
step_or_fail!(self, self.machine_st.p += 1);
|
||||
}
|
||||
&Instruction::ExecuteInvErf => {
|
||||
self.inverf();
|
||||
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
||||
}
|
||||
&Instruction::CallInvErfc => {
|
||||
self.inverfc();
|
||||
step_or_fail!(self, self.machine_st.p += 1);
|
||||
}
|
||||
&Instruction::ExecuteInvErfc => {
|
||||
self.inverfc();
|
||||
step_or_fail!(self, self.machine_st.p = self.machine_st.cp);
|
||||
}
|
||||
&Instruction::CallCryptoCurveScalarMult => {
|
||||
self.crypto_curve_scalar_mult();
|
||||
step_or_fail!(self, self.machine_st.p += 1);
|
||||
|
||||
@@ -84,6 +84,8 @@ use sha3::{Sha3_224, Sha3_256, Sha3_384, Sha3_512};
|
||||
|
||||
use crrl::{ed25519, secp256k1, x25519};
|
||||
|
||||
pub(crate) mod special_math;
|
||||
|
||||
#[cfg(feature = "tls")]
|
||||
use native_tls::{Identity, TlsAcceptor, TlsConnector};
|
||||
|
||||
|
||||
121
src/machine/system_calls/special_math.rs
Normal file
121
src/machine/system_calls/special_math.rs
Normal file
@@ -0,0 +1,121 @@
|
||||
use crate::machine::Number;
|
||||
use crate::offset_table::OffsetTable;
|
||||
use crate::Machine;
|
||||
use ordered_float::OrderedFloat;
|
||||
use puruspe::beta::*;
|
||||
use puruspe::error::*;
|
||||
use puruspe::gamma::*;
|
||||
|
||||
macro_rules! number_as_f64 {
|
||||
($self: ident, $reg: literal) => {{
|
||||
match Number::try_from(($self.deref_register($reg), &$self.machine_st.arena.f64_tbl)) {
|
||||
Ok(Number::Float(n)) => n.into_inner(),
|
||||
Ok(Number::Fixnum(n)) => n.get_num() as f64,
|
||||
Ok(Number::Integer(n)) => n.to_f64().value(),
|
||||
_ => {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! return_f64_reg {
|
||||
($self: ident, $val: ident, $reg: literal) => {{
|
||||
let return_value = $self.deref_register($reg);
|
||||
$self.machine_st.unify_f64($val, return_value);
|
||||
}};
|
||||
}
|
||||
|
||||
impl Machine {
|
||||
#[inline(always)]
|
||||
pub(crate) fn erf(&mut self) {
|
||||
let x = number_as_f64!(self, 1);
|
||||
let erf_x = float_alloc!(erf(x), self.machine_st.arena);
|
||||
return_f64_reg!(self, erf_x, 2);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn erfc(&mut self) {
|
||||
let x = number_as_f64!(self, 1);
|
||||
let erfc_x = float_alloc!(erfc(x), self.machine_st.arena);
|
||||
return_f64_reg!(self, erfc_x, 2);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn inverf(&mut self) {
|
||||
let erf_x = number_as_f64!(self, 1);
|
||||
let x = float_alloc!(inverf(erf_x), self.machine_st.arena);
|
||||
return_f64_reg!(self, x, 2);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn inverfc(&mut self) {
|
||||
let erfc_x = number_as_f64!(self, 1);
|
||||
let x = float_alloc!(inverfc(erfc_x), self.machine_st.arena);
|
||||
return_f64_reg!(self, x, 2);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn gamma(&mut self) {
|
||||
let x = number_as_f64!(self, 1);
|
||||
let gamma_x = float_alloc!(gamma(x), self.machine_st.arena);
|
||||
return_f64_reg!(self, gamma_x, 2);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn gammp(&mut self) {
|
||||
let a = number_as_f64!(self, 1);
|
||||
let x = number_as_f64!(self, 2);
|
||||
let gammp_a_x = float_alloc!(gammp(a, x), self.machine_st.arena);
|
||||
return_f64_reg!(self, gammp_a_x, 3);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn gammq(&mut self) {
|
||||
let a = number_as_f64!(self, 1);
|
||||
let x = number_as_f64!(self, 2);
|
||||
let gammq_a_x = float_alloc!(gammq(a, x), self.machine_st.arena);
|
||||
return_f64_reg!(self, gammq_a_x, 3);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn invgammp(&mut self) {
|
||||
let p = number_as_f64!(self, 1);
|
||||
let a = number_as_f64!(self, 2);
|
||||
let x = float_alloc!(invgammp(p, a), self.machine_st.arena);
|
||||
return_f64_reg!(self, x, 3);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn ln_gamma(&mut self) {
|
||||
let x = number_as_f64!(self, 1);
|
||||
let ln_gamma_x = float_alloc!(ln_gamma(x), self.machine_st.arena);
|
||||
return_f64_reg!(self, ln_gamma_x, 2);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn beta(&mut self) {
|
||||
let x = number_as_f64!(self, 1);
|
||||
let y = number_as_f64!(self, 2);
|
||||
let beta_x_y = float_alloc!(beta(x, y), self.machine_st.arena);
|
||||
return_f64_reg!(self, beta_x_y, 3);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn betai(&mut self) {
|
||||
let a = number_as_f64!(self, 1);
|
||||
let b = number_as_f64!(self, 2);
|
||||
let x = number_as_f64!(self, 3);
|
||||
let betai_a_b_x = float_alloc!(betai(a, b, x), self.machine_st.arena);
|
||||
return_f64_reg!(self, betai_a_b_x, 4);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn invbetai(&mut self) {
|
||||
let a = number_as_f64!(self, 1);
|
||||
let b = number_as_f64!(self, 2);
|
||||
let p = number_as_f64!(self, 3);
|
||||
let x = float_alloc!(invbetai(a, b, p), self.machine_st.arena);
|
||||
return_f64_reg!(self, x, 4);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user