Merge pull request #3320 from Skgland/all-pure-rust

add a feature for enabling all features that don't pull in non pure rust dependencies
This commit is contained in:
Mark Thom
2026-05-25 14:36:04 -06:00
committed by GitHub
17 changed files with 428 additions and 377 deletions

View File

@@ -247,11 +247,12 @@ impl<T: CopierTarget> CopyTermState<T> {
self.trail
.push((TrailRef::pstr_loc(pstr_loc_idx), old_cell));
let old_tail_idx = if (pstr_loc + offset + 1) % Heap::heap_cell_alignment() == 0 {
cell_index!(pstr_loc + offset) + 2
} else {
cell_index!(pstr_loc + offset) + 1
};
let old_tail_idx =
if (pstr_loc + offset + 1).is_multiple_of(Heap::heap_cell_alignment()) {
cell_index!(pstr_loc + offset) + 2
} else {
cell_index!(pstr_loc + offset) + 1
};
let tail_cell = self.target[old_tail_idx];

View File

@@ -549,7 +549,7 @@ impl VariableClassifier {
let first_branch_num = Arc::new(self.current_branch_num.split());
let branches: Vec<_> = std::iter::once(head)
.chain(unfold_by_str(tail, atom!(";")).into_iter())
.chain(unfold_by_str(tail, atom!(";")))
.collect();
let mut branch_numbers = vec![first_branch_num];
@@ -571,7 +571,7 @@ impl VariableClassifier {
self.current_branch_num.halve_delta(),
)));
let iter = branches.into_iter().zip(branch_numbers.into_iter());
let iter = branches.into_iter().zip(branch_numbers);
let final_disjunct_loc = state_stack.len();
for (term, branch_num) in iter.rev() {

View File

@@ -577,7 +577,7 @@ impl Heap {
// takes a heap index, returns a cell index
#[inline]
pub const fn pstr_tail_idx(pstr_zero_byte_loc: usize) -> usize {
if (pstr_zero_byte_loc + 1) % Heap::heap_cell_alignment() == 0 {
if (pstr_zero_byte_loc + 1).is_multiple_of(Heap::heap_cell_alignment()) {
cell_index!(pstr_zero_byte_loc) + 2
} else {
cell_index!(pstr_zero_byte_loc) + 1

View File

@@ -937,6 +937,7 @@ impl Permission {
}
#[derive(Debug, Clone, Copy)]
#[cfg_attr(not(feature = "ffi"), expect(dead_code))]
pub(crate) enum DomainErrorType {
IOMode,
NotLessThanZero,
@@ -987,6 +988,7 @@ impl DomainErrorType {
// from 7.12.2 f) of 13211-1:1995
#[derive(Debug, Clone, Copy)]
#[cfg_attr(not(feature = "ffi"), expect(dead_code))]
pub(crate) enum RepFlag {
Character,
CharacterCode,
@@ -1178,6 +1180,7 @@ impl MachineState {
}
#[derive(Debug)]
#[cfg_attr(not(feature = "ffi"), expect(dead_code))]
pub enum ExistenceError {
Module(Atom),
ModuleSource(ModuleSource),

View File

@@ -548,8 +548,7 @@ impl MachineState {
return true;
}
// use strict_add once msrv is >= 1.91.0
self.cwil.global_count = self.cwil.global_count.checked_add(1).unwrap();
self.cwil.global_count = self.cwil.global_count.strict_add(1);
if let Some(&(ref limit, block)) = self.cwil.limits.last() {
if self.cwil.local_count == *limit {
@@ -651,7 +650,7 @@ impl MachineState {
mut var_list: Vec<(VarKey, HeapCellValue, usize)>,
singleton_heap_list: HeapCellValue,
) -> CallResult {
var_list.sort_by(|(_, _, idx_1), (_, _, idx_2)| idx_1.cmp(idx_2));
var_list.sort_by_key(|(_, _, idx_1)| *idx_1);
let singleton_addr = self.registers[3];
unify_fn!(*self, singleton_heap_list, singleton_addr);
@@ -1128,8 +1127,7 @@ impl CWIL {
}
pub(crate) fn add_limit(&mut self, mut limit: u128, block: usize) -> u128 {
// use strict_add once msrv is >= 1.91.0
limit = limit.checked_add(self.local_count).unwrap();
limit = limit.strict_add(self.local_count);
match self.limits.last() {
Some((ref inner_limit, _)) if *inner_limit <= limit => {}

View File

@@ -195,8 +195,7 @@ impl Stack {
// exposed provenance, we need to expose the provenance here, even though we don't
// actually use the value for anything. This is a reminder that `expose_provenance`
// isn't just a cast from a pointer to an integer but has actual side effects.
// FIXME(msrv) remove the as_ptr() call once MSRV reaches 1.89.0
cell_ptr.as_ptr().expose_provenance();
cell_ptr.expose_provenance();
offset += mem::size_of::<HeapCellValue>();
}
@@ -228,8 +227,7 @@ impl Stack {
// exposed provenance, we need to expose the provenance here, even though we don't
// actually use the value for anything. This is a reminder that `expose_provenance`
// isn't just a cast from a pointer to an integer but has actual side effects.
// FIXME(msrv) remove as_ptr() call once msrv reaches 1.89.0
cell_ptr.as_ptr().expose_provenance();
cell_ptr.expose_provenance();
offset += mem::size_of::<HeapCellValue>();
}

View File

@@ -23,6 +23,8 @@ use std::fmt::Debug;
use std::fs::{File, OpenOptions};
use std::hash::Hash;
use std::io;
use std::io::PipeReader;
use std::io::PipeWriter;
use std::io::{Cursor, ErrorKind, Read, Seek, SeekFrom, Write};
use std::mem::ManuallyDrop;
use std::net::{Shutdown, TcpStream};
@@ -38,9 +40,6 @@ use native_tls::TlsStream;
#[cfg(feature = "http")]
use warp::hyper;
mod compat;
pub use compat::*;
#[derive(Debug, Specifier, Clone, Copy, PartialEq, Eq, Hash)]
#[bits = 1]
pub enum StreamType {

View File

@@ -1,72 +0,0 @@
#[cfg(rust_version = "1.87.0")]
pub use ge_1_87_0::{PipeReader, PipeWriter};
#[cfg(not(rust_version = "1.87.0"))]
pub use lt_1_87_0::{PipeReader, PipeWriter};
#[cfg(not(rust_version = "1.87.0"))]
pub(crate) use lt_1_87_0::PipeReaderInner;
#[cfg(not(rust_version = "1.87.0"))]
mod lt_1_87_0 {
use std::process::{ChildStderr, ChildStdout};
pub type PipeWriter = std::process::ChildStdin;
#[derive(Debug)]
pub struct PipeReader(pub(crate) PipeReaderInner);
#[derive(Debug)]
pub(crate) enum PipeReaderInner {
Stdout(ChildStdout),
Stderr(ChildStderr),
}
impl std::io::Read for PipeReader {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
match &mut self.0 {
PipeReaderInner::Stdout(child_stdout) => child_stdout.read(buf),
PipeReaderInner::Stderr(child_stderr) => child_stderr.read(buf),
}
}
fn read_vectored(
&mut self,
bufs: &mut [std::io::IoSliceMut<'_>],
) -> std::io::Result<usize> {
match &mut self.0 {
PipeReaderInner::Stdout(child_stdout) => child_stdout.read_vectored(bufs),
PipeReaderInner::Stderr(child_stderr) => child_stderr.read_vectored(bufs),
}
}
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> std::io::Result<usize> {
match &mut self.0 {
PipeReaderInner::Stdout(child_stdout) => child_stdout.read_to_end(buf),
PipeReaderInner::Stderr(child_stderr) => child_stderr.read_to_end(buf),
}
}
fn read_to_string(&mut self, buf: &mut String) -> std::io::Result<usize> {
match &mut self.0 {
PipeReaderInner::Stdout(child_stdout) => child_stdout.read_to_string(buf),
PipeReaderInner::Stderr(child_stderr) => child_stderr.read_to_string(buf),
}
}
fn read_exact(&mut self, buf: &mut [u8]) -> std::io::Result<()> {
match &mut self.0 {
PipeReaderInner::Stdout(child_stdout) => child_stdout.read_exact(buf),
PipeReaderInner::Stderr(child_stderr) => child_stderr.read_exact(buf),
}
}
}
}
#[cfg(rust_version = "1.87.0")]
mod ge_1_87_0 {
#![allow(clippy::incompatible_msrv)]
pub type PipeReader = std::io::PipeReader;
pub type PipeWriter = std::io::PipeWriter;
}

View File

@@ -53,7 +53,6 @@ use std::mem;
#[cfg(feature = "http")]
use std::net::{SocketAddr, ToSocketAddrs};
use std::net::{TcpListener, TcpStream};
use std::num::NonZeroU32;
use std::process;
use std::process::Child;
use std::process::Stdio;
@@ -74,11 +73,13 @@ use crossterm::event::{read, Event, KeyCode, KeyEvent, KeyEventKind, KeyModifier
use crossterm::terminal::{disable_raw_mode, enable_raw_mode};
use blake2::{Blake2b512, Blake2s256};
use ring::rand::{SecureRandom, SystemRandom};
use ring::{digest, hkdf, hmac, pbkdf2};
#[cfg(feature = "crypto-full")]
use ring::aead;
use ring::{
aead, digest, hkdf, hmac, pbkdf2,
rand::{SecureRandom, SystemRandom},
};
use ripemd::{Digest, Ripemd160};
use sha3::{Sha3_224, Sha3_256, Sha3_384, Sha3_512};
@@ -96,8 +97,6 @@ use roxmltree;
use futures::future;
#[cfg(feature = "http")]
use reqwest::Url;
use tokio::runtime::Handle;
use tokio::task;
#[cfg(feature = "http")]
use warp::hyper::header::{HeaderName, HeaderValue};
#[cfg(feature = "http")]
@@ -4403,6 +4402,8 @@ impl Machine {
#[cfg(feature = "http")]
#[inline(always)]
pub(crate) fn http_open(&mut self) -> CallResult {
use tokio::task;
let address_sink = self.deref_register(1);
let method = read_heap_cell!(self.deref_register(3),
(HeapCellValueTag::Atom, (name, arity)) => {
@@ -4466,7 +4467,7 @@ impl Machine {
// do it!
task::block_in_place(move || {
match Handle::current().block_on(req.send()) {
match tokio::runtime::Handle::current().block_on(req.send()) {
Ok(resp) => {
// status code
let status = resp.status().as_u16();
@@ -7843,22 +7844,33 @@ impl Machine {
#[inline(always)]
pub(crate) fn crypto_random_byte(&mut self) {
let arg = self.machine_st.registers[1];
let mut bytes: [u8; 1] = [0];
#[cfg(feature = "crypto-full")]
{
let arg = self.machine_st.registers[1];
let mut bytes: [u8; 1] = [0];
match rng().fill(&mut bytes) {
Ok(()) => {}
Err(_) => {
// the error payload here is of type 'Unspecified',
// which contains no information whatsoever. So, for now,
// just fail.
self.machine_st.fail = true;
return;
match rng().fill(&mut bytes) {
Ok(()) => {}
Err(_) => {
// the error payload here is of type 'Unspecified',
// which contains no information whatsoever. So, for now,
// just fail.
self.machine_st.fail = true;
return;
}
}
let byte = Fixnum::build_with(bytes[0]);
self.machine_st.unify_fixnum(byte, arg);
}
let byte = Fixnum::build_with(bytes[0]);
self.machine_st.unify_fixnum(byte, arg);
#[cfg(not(feature = "crypto-full"))]
{
let stub_gen = || functor_stub(atom!("crypto_random_byte"), 1);
let err = self.machine_st.missing_feature_error(atom!("crypto"));
let exception = self.machine_st.error_form(err, stub_gen());
self.machine_st.throw_exception(exception);
}
}
#[inline(always)]
@@ -7990,29 +8002,40 @@ impl Machine {
)
}
_ => {
let ints = digest::digest(
match algorithm {
atom!("sha256") => &digest::SHA256,
atom!("sha384") => &digest::SHA384,
atom!("sha512") => &digest::SHA512,
atom!("sha512_256") => &digest::SHA512_256,
_ => {
unreachable!()
}
},
&bytes,
);
#[cfg(feature = "crypto-full")]
{
let ints = digest::digest(
match algorithm {
atom!("sha256") => &digest::SHA256,
atom!("sha384") => &digest::SHA384,
atom!("sha512") => &digest::SHA512,
atom!("sha512_256") => &digest::SHA512_256,
_ => {
unreachable!()
}
},
&bytes,
);
step_or_resource_error!(
self.machine_st,
sized_iter_to_heap_list(
&mut self.machine_st.heap,
ints.as_ref().len(),
ints.as_ref()
.iter()
.map(|b| fixnum_as_cell!(Fixnum::build_with(*b)))
step_or_resource_error!(
self.machine_st,
sized_iter_to_heap_list(
&mut self.machine_st.heap,
ints.as_ref().len(),
ints.as_ref()
.iter()
.map(|b| fixnum_as_cell!(Fixnum::build_with(*b)))
)
)
)
}
#[cfg(not(feature = "crypto-full"))]
{
let stub_gen = || functor_stub(atom!("crypto_data_hash"), 1);
let err = self.machine_st.missing_feature_error(atom!("crypto"));
let exception = self.machine_st.error_form(err, stub_gen());
self.machine_st.throw_exception(exception);
return;
}
}
};
@@ -8021,168 +8044,201 @@ impl Machine {
#[inline(always)]
pub(crate) fn crypto_hmac(&mut self) {
let encoding = cell_as_atom!(self.deref_register(2));
let data = self.string_encoding_bytes(self.machine_st.registers[1], encoding);
let stub_gen = || functor_stub(atom!("crypto_data_hash"), 3);
let key = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[3], stub_gen);
#[cfg(feature = "crypto-full")]
{
let encoding = cell_as_atom!(self.deref_register(2));
let data = self.string_encoding_bytes(self.machine_st.registers[1], encoding);
let algorithm = cell_as_atom!(self.deref_register(5));
let ralg = match algorithm {
atom!("sha256") => hmac::HMAC_SHA256,
atom!("sha384") => hmac::HMAC_SHA384,
atom!("sha512") => hmac::HMAC_SHA512,
_ => {
unreachable!()
}
};
let key = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[3], stub_gen);
let rkey = hmac::Key::new(ralg, key.as_ref());
let tag = hmac::sign(&rkey, &data);
let algorithm = cell_as_atom!(self.deref_register(5));
let ralg = match algorithm {
atom!("sha256") => hmac::HMAC_SHA256,
atom!("sha384") => hmac::HMAC_SHA384,
atom!("sha512") => hmac::HMAC_SHA512,
_ => {
unreachable!()
}
};
let ints_list = step_or_resource_error!(
self.machine_st,
sized_iter_to_heap_list(
&mut self.machine_st.heap,
tag.as_ref().len(),
tag.as_ref()
.iter()
.map(|b| fixnum_as_cell!(Fixnum::build_with(*b)))
)
);
let rkey = hmac::Key::new(ralg, key.as_ref());
let tag = hmac::sign(&rkey, &data);
unify!(self.machine_st, self.machine_st.registers[4], ints_list);
let ints_list = step_or_resource_error!(
self.machine_st,
sized_iter_to_heap_list(
&mut self.machine_st.heap,
tag.as_ref().len(),
tag.as_ref()
.iter()
.map(|b| fixnum_as_cell!(Fixnum::build_with(*b)))
)
);
unify!(self.machine_st, self.machine_st.registers[4], ints_list);
}
#[cfg(not(feature = "crypto-full"))]
{
let err = self.machine_st.missing_feature_error(atom!("crypto"));
let exception = self.machine_st.error_form(err, stub_gen());
self.machine_st.throw_exception(exception);
}
}
#[inline(always)]
pub(crate) fn crypto_data_hkdf(&mut self) {
let encoding = cell_as_atom!(self.deref_register(2));
let data = self.string_encoding_bytes(self.machine_st.registers[1], encoding);
let stub1_gen = || functor_stub(atom!("crypto_data_hkdf"), 4);
let salt = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[3], stub1_gen);
let stub2_gen = || functor_stub(atom!("crypto_data_hkdf"), 4);
let info = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[4], stub2_gen);
#[cfg(feature = "crypto-full")]
{
let encoding = cell_as_atom!(self.deref_register(2));
let data = self.string_encoding_bytes(self.machine_st.registers[1], encoding);
let algorithm = cell_as_atom!(self.deref_register(5));
let salt = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[3], stub1_gen);
let length = self.deref_register(6);
let stub2_gen = || functor_stub(atom!("crypto_data_hkdf"), 4);
let info = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[4], stub2_gen);
let length = match Number::try_from((length, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Fixnum(n)) => usize::try_from(n.get_num()).unwrap(),
Ok(Number::Integer(n)) => match (&*n).try_into() as Result<usize, _> {
Ok(u) => u,
let algorithm = cell_as_atom!(self.deref_register(5));
let length = self.deref_register(6);
let length = match Number::try_from((length, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Fixnum(n)) => usize::try_from(n.get_num()).unwrap(),
Ok(Number::Integer(n)) => match (&*n).try_into() as Result<usize, _> {
Ok(u) => u,
_ => {
self.machine_st.fail = true;
return;
}
},
_ => {
self.machine_st.fail = true;
return;
}
},
_ => {
unreachable!()
}
};
let ints_list = {
let digest_alg = match algorithm {
atom!("sha256") => hkdf::HKDF_SHA256,
atom!("sha384") => hkdf::HKDF_SHA384,
atom!("sha512") => hkdf::HKDF_SHA512,
_ => {
self.machine_st.fail = true;
return;
unreachable!()
}
};
let salt = hkdf::Salt::new(digest_alg, &salt);
let mut bytes: Vec<u8> = vec![0; length];
let ints_list = {
let digest_alg = match algorithm {
atom!("sha256") => hkdf::HKDF_SHA256,
atom!("sha384") => hkdf::HKDF_SHA384,
atom!("sha512") => hkdf::HKDF_SHA512,
_ => {
self.machine_st.fail = true;
return;
}
};
match salt.extract(&data).expand(&[&info[..]], MyKey(length)) {
Ok(r) => {
r.fill(&mut bytes).unwrap();
}
_ => {
self.machine_st.fail = true;
return;
}
}
let salt = hkdf::Salt::new(digest_alg, &salt);
let mut bytes: Vec<u8> = vec![0; length];
step_or_resource_error!(
self.machine_st,
sized_iter_to_heap_list(
&mut self.machine_st.heap,
bytes.len(),
bytes
.iter()
.map(|b| fixnum_as_cell!(Fixnum::build_with(*b)))
)
)
};
unify!(self.machine_st, self.machine_st.registers[7], ints_list);
}
#[inline(always)]
pub(crate) fn crypto_password_hash(&mut self) {
let stub1_gen = || functor_stub(atom!("crypto_password_hash"), 3);
let data = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[1], stub1_gen);
let stub2_gen = || functor_stub(atom!("crypto_password_hash"), 3);
let salt = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[2], stub2_gen);
let iterations = self.deref_register(3);
let iterations = match Number::try_from((iterations, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Fixnum(n)) => u64::try_from(n.get_num()).unwrap(),
Ok(Number::Integer(n)) => {
let n: Result<u64, _> = (&*n).try_into();
match n {
Ok(i) => i,
match salt.extract(&data).expand(&[&info[..]], MyKey(length)) {
Ok(r) => {
r.fill(&mut bytes).unwrap();
}
_ => {
self.machine_st.fail = true;
return;
}
}
}
_ => {
unreachable!()
}
};
let ints_list = {
let mut bytes = [0u8; digest::SHA512_OUTPUT_LEN];
pbkdf2::derive(
pbkdf2::PBKDF2_HMAC_SHA512,
NonZeroU32::new(iterations as u32).unwrap(),
&salt,
&data,
&mut bytes,
);
step_or_resource_error!(
self.machine_st,
sized_iter_to_heap_list(
&mut self.machine_st.heap,
bytes.len(),
bytes
.iter()
.map(|b| fixnum_as_cell!(Fixnum::build_with(*b)))
step_or_resource_error!(
self.machine_st,
sized_iter_to_heap_list(
&mut self.machine_st.heap,
bytes.len(),
bytes
.iter()
.map(|b| fixnum_as_cell!(Fixnum::build_with(*b)))
)
)
)
};
};
unify!(self.machine_st, self.machine_st.registers[4], ints_list);
unify!(self.machine_st, self.machine_st.registers[7], ints_list);
}
#[cfg(not(feature = "crypto-full"))]
{
let err = self.machine_st.missing_feature_error(atom!("crypto"));
let exception = self.machine_st.error_form(err, stub1_gen());
self.machine_st.throw_exception(exception);
}
}
#[inline(always)]
pub(crate) fn crypto_password_hash(&mut self) {
let stub1_gen = || functor_stub(atom!("crypto_password_hash"), 3);
#[cfg(feature = "crypto-full")]
{
use std::num::NonZeroU32;
let data = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[1], stub1_gen);
let stub2_gen = || functor_stub(atom!("crypto_password_hash"), 3);
let salt = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[2], stub2_gen);
let iterations = self.deref_register(3);
let iterations = match Number::try_from((iterations, &self.machine_st.arena.f64_tbl)) {
Ok(Number::Fixnum(n)) => u64::try_from(n.get_num()).unwrap(),
Ok(Number::Integer(n)) => {
let n: Result<u64, _> = (&*n).try_into();
match n {
Ok(i) => i,
_ => {
self.machine_st.fail = true;
return;
}
}
}
_ => {
unreachable!()
}
};
let ints_list = {
let mut bytes = [0u8; digest::SHA512_OUTPUT_LEN];
pbkdf2::derive(
pbkdf2::PBKDF2_HMAC_SHA512,
NonZeroU32::new(iterations as u32).unwrap(),
&salt,
&data,
&mut bytes,
);
step_or_resource_error!(
self.machine_st,
sized_iter_to_heap_list(
&mut self.machine_st.heap,
bytes.len(),
bytes
.iter()
.map(|b| fixnum_as_cell!(Fixnum::build_with(*b)))
)
)
};
unify!(self.machine_st, self.machine_st.registers[4], ints_list);
}
#[cfg(not(feature = "crypto-full"))]
{
let err = self.machine_st.missing_feature_error(atom!("crypto"));
let exception = self.machine_st.error_form(err, stub1_gen());
self.machine_st.throw_exception(exception);
}
}
#[cfg(feature = "crypto-full")]
@@ -8304,109 +8360,153 @@ impl Machine {
#[inline(always)]
pub(crate) fn crypto_curve_scalar_mult(&mut self) {
let stub_gen = || functor_stub(atom!("crypto_curve_scalar_mult"), 4);
let scalar_bytes = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[2], stub_gen);
let point_bytes = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[3], stub_gen);
let mut point = secp256k1::Point::decode(&point_bytes).unwrap();
let scalar = secp256k1::Scalar::decode_reduce(&scalar_bytes);
point *= scalar;
{
let scalar_bytes = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[2], stub_gen);
let point_bytes = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[3], stub_gen);
let uncompressed = step_or_resource_error!(
self.machine_st,
self.u8s_to_string(&point.encode_uncompressed())
);
let mut point = secp256k1::Point::decode(&point_bytes).unwrap();
let scalar = secp256k1::Scalar::decode_reduce(&scalar_bytes);
point *= scalar;
unify!(self.machine_st, self.machine_st.registers[4], uncompressed);
let uncompressed = step_or_resource_error!(
self.machine_st,
self.u8s_to_string(&point.encode_uncompressed())
);
unify!(self.machine_st, self.machine_st.registers[4], uncompressed);
}
{
let err = self.machine_st.missing_feature_error(atom!("crypto"));
let exception = self.machine_st.error_form(err, stub_gen());
self.machine_st.throw_exception(exception);
}
}
#[inline(always)]
pub(crate) fn ed25519_seed_to_public_key(&mut self) {
let stub_gen = || functor_stub(atom!("ed25519_seed_keypair"), 2);
let seed_bytes = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[1], stub_gen);
let skey = ed25519::PrivateKey::from_seed(&seed_bytes);
{
let seed_bytes = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[1], stub_gen);
let complete_string = step_or_resource_error!(
self.machine_st,
self.u8s_to_string(skey.public_key.encoded.as_ref())
);
let skey = ed25519::PrivateKey::from_seed(&seed_bytes);
unify!(
self.machine_st,
self.machine_st.registers[2],
complete_string
);
let complete_string = step_or_resource_error!(
self.machine_st,
self.u8s_to_string(skey.public_key.encoded.as_ref())
);
unify!(
self.machine_st,
self.machine_st.registers[2],
complete_string
);
}
{
let err = self.machine_st.missing_feature_error(atom!("crypto"));
let exception = self.machine_st.error_form(err, stub_gen());
self.machine_st.throw_exception(exception);
}
}
#[inline(always)]
pub(crate) fn ed25519_sign_raw(&mut self) {
let stub_gen = || functor_stub(atom!("ed25519_sign"), 4);
let seed_bytes = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[1], stub_gen);
let skey = ed25519::PrivateKey::from_seed(&seed_bytes);
{
let seed_bytes = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[1], stub_gen);
let encoding = cell_as_atom!(self.deref_register(3));
let data = self.string_encoding_bytes(self.machine_st.registers[2], encoding);
let skey = ed25519::PrivateKey::from_seed(&seed_bytes);
let sig = skey.sign_raw(&data);
let sig_list = step_or_resource_error!(
self.machine_st,
sized_iter_to_heap_list(
&mut self.machine_st.heap,
sig.as_ref().len(),
sig.as_ref()
.iter()
.map(|b| fixnum_as_cell!(Fixnum::build_with(*b)))
)
);
let encoding = cell_as_atom!(self.deref_register(3));
let data = self.string_encoding_bytes(self.machine_st.registers[2], encoding);
unify!(self.machine_st, self.machine_st.registers[4], sig_list);
let sig = skey.sign_raw(&data);
let sig_list = step_or_resource_error!(
self.machine_st,
sized_iter_to_heap_list(
&mut self.machine_st.heap,
sig.as_ref().len(),
sig.as_ref()
.iter()
.map(|b| fixnum_as_cell!(Fixnum::build_with(*b)))
)
);
unify!(self.machine_st, self.machine_st.registers[4], sig_list);
}
{
let err = self.machine_st.missing_feature_error(atom!("crypto"));
let exception = self.machine_st.error_form(err, stub_gen());
self.machine_st.throw_exception(exception);
}
}
#[inline(always)]
pub(crate) fn ed25519_verify_raw(&mut self) {
let key_bytes = self.string_encoding_bytes(self.machine_st.registers[1], atom!("octet"));
let pkey = ed25519::PublicKey::decode(&key_bytes).unwrap();
let encoding = cell_as_atom!(self.deref_register(3));
let data = self.string_encoding_bytes(self.machine_st.registers[2], encoding);
let stub_gen = || functor_stub(atom!("ed25519_verify"), 4);
let signature = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[4], stub_gen);
{
let key_bytes =
self.string_encoding_bytes(self.machine_st.registers[1], atom!("octet"));
let pkey = ed25519::PublicKey::decode(&key_bytes).unwrap();
self.machine_st.fail = !pkey.verify_raw(&signature, &data);
let encoding = cell_as_atom!(self.deref_register(3));
let data = self.string_encoding_bytes(self.machine_st.registers[2], encoding);
let signature = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[4], stub_gen);
self.machine_st.fail = !pkey.verify_raw(&signature, &data);
}
{
let err = self.machine_st.missing_feature_error(atom!("crypto"));
let exception = self.machine_st.error_form(err, stub_gen());
self.machine_st.throw_exception(exception);
}
}
#[inline(always)]
pub(crate) fn curve25519_scalar_mult(&mut self) {
let stub1_gen = || functor_stub(atom!("curve25519_scalar_mult"), 3);
let scalar_bytes = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[1], stub1_gen);
let stub2_gen = || functor_stub(atom!("curve25519_scalar_mult"), 3);
let point_bytes = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[2], stub2_gen);
let stub_gen = || functor_stub(atom!("curve25519_scalar_mult"), 3);
let result = x25519::x25519(
&<[u8; 32]>::try_from(&point_bytes[..]).unwrap(),
&<[u8; 32]>::try_from(&scalar_bytes[..]).unwrap(),
);
{
let scalar_bytes = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[1], stub_gen);
let point_bytes = self
.machine_st
.integers_to_bytevec(self.machine_st.registers[2], stub_gen);
let string = step_or_resource_error!(self.machine_st, self.u8s_to_string(&result[..]));
let result = x25519::x25519(
&<[u8; 32]>::try_from(&point_bytes[..]).unwrap(),
&<[u8; 32]>::try_from(&scalar_bytes[..]).unwrap(),
);
unify!(self.machine_st, self.machine_st.registers[3], string);
let string = step_or_resource_error!(self.machine_st, self.u8s_to_string(&result[..]));
unify!(self.machine_st, self.machine_st.registers[3], string);
}
{
let err = self.machine_st.missing_feature_error(atom!("crypto"));
let exception = self.machine_st.error_form(err, stub_gen());
self.machine_st.throw_exception(exception);
}
}
#[inline(always)]
@@ -8848,36 +8948,27 @@ impl Machine {
Some(atom!("std")) => Stdio::inherit(),
Some(atom!("null")) => Stdio::null(),
Some(atom!("pipe")) => {
#[cfg(rust_version = "1.87.0")]
#[allow(clippy::incompatible_msrv)]
{
let (reader, writer) = match std::io::pipe() {
Ok(pipe_pair) => pipe_pair,
Err(_) => {
return Err(self.machine_st.open_permission_error(
atom!("anonymous_pipe"),
atom!("process_create"),
3,
));
}
};
let (reader, writer) = match std::io::pipe() {
Ok(pipe_pair) => pipe_pair,
Err(_) => {
return Err(self.machine_st.open_permission_error(
atom!("anonymous_pipe"),
atom!("process_create"),
3,
));
}
};
let stream = Stream::from_pipe_writer(writer, &mut self.machine_st.arena);
let stream = Stream::from_pipe_writer(writer, &mut self.machine_st.arena);
self.indices
.add_stream(stream, atom!("process_create"), 3)
.map_err(|stub_gen| stub_gen(&mut self.machine_st))?;
self.indices
.add_stream(stream, atom!("process_create"), 3)
.map_err(|stub_gen| stub_gen(&mut self.machine_st))?;
self.machine_st
.bind(args[1].as_var().unwrap(), stream.into());
self.machine_st
.bind(args[1].as_var().unwrap(), stream.into());
Stdio::from(reader)
}
#[cfg(not(rust_version = "1.87.0"))]
{
Stdio::piped()
}
Stdio::from(reader)
}
Some(atom!("file")) => {
let path = self.machine_st.value_to_str_like(args[1]).unwrap();
@@ -9509,6 +9600,7 @@ impl Machine {
}
}
#[cfg(feature = "crypto-full")]
fn rng() -> &'static dyn SecureRandom {
use std::ops::Deref;
@@ -9517,8 +9609,10 @@ fn rng() -> &'static dyn SecureRandom {
RANDOM.deref()
}
#[cfg(feature = "crypto-full")]
struct MyKey<T: core::fmt::Debug + PartialEq>(T);
#[cfg(feature = "crypto-full")]
impl hkdf::KeyType for MyKey<usize> {
fn len(&self) -> usize {
self.0