Skip to content

Commit fe0b854

Browse files
committed
pymodule for _random
1 parent 84527b0 commit fe0b854

File tree

1 file changed

+96
-100
lines changed

1 file changed

+96
-100
lines changed

vm/src/stdlib/random.rs

Lines changed: 96 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,127 +1,123 @@
11
//! Random module.
22
3-
use std::cell::RefCell;
4-
5-
use num_bigint::{BigInt, Sign};
6-
use num_traits::Signed;
7-
use rand::RngCore;
8-
9-
use crate::function::OptionalOption;
10-
use crate::obj::objint::PyIntRef;
11-
use crate::obj::objtype::PyClassRef;
12-
use crate::pyobject::{PyClassImpl, PyObjectRef, PyRef, PyResult, PyValue};
13-
use crate::VirtualMachine;
14-
15-
#[derive(Debug)]
16-
enum PyRng {
17-
Std(rand::rngs::ThreadRng),
18-
MT(Box<mt19937::MT19937>),
19-
}
20-
21-
impl Default for PyRng {
22-
fn default() -> Self {
23-
PyRng::Std(rand::thread_rng())
3+
pub(crate) use _random::make_module;
4+
5+
#[pymodule]
6+
mod _random {
7+
use crate::function::OptionalOption;
8+
use crate::obj::objint::PyIntRef;
9+
use crate::obj::objtype::PyClassRef;
10+
use crate::pyobject::{PyClassImpl, PyRef, PyResult, PyValue};
11+
use crate::VirtualMachine;
12+
use num_bigint::{BigInt, Sign};
13+
use num_traits::Signed;
14+
use rand::RngCore;
15+
use std::cell::RefCell;
16+
17+
#[derive(Debug)]
18+
enum PyRng {
19+
Std(rand::rngs::ThreadRng),
20+
MT(Box<mt19937::MT19937>),
2421
}
25-
}
2622

27-
impl RngCore for PyRng {
28-
fn next_u32(&mut self) -> u32 {
29-
match self {
30-
Self::Std(s) => s.next_u32(),
31-
Self::MT(m) => m.next_u32(),
23+
impl Default for PyRng {
24+
fn default() -> Self {
25+
PyRng::Std(rand::thread_rng())
3226
}
3327
}
34-
fn next_u64(&mut self) -> u64 {
35-
match self {
36-
Self::Std(s) => s.next_u64(),
37-
Self::MT(m) => m.next_u64(),
28+
29+
impl RngCore for PyRng {
30+
fn next_u32(&mut self) -> u32 {
31+
match self {
32+
Self::Std(s) => s.next_u32(),
33+
Self::MT(m) => m.next_u32(),
34+
}
3835
}
39-
}
40-
fn fill_bytes(&mut self, dest: &mut [u8]) {
41-
match self {
42-
Self::Std(s) => s.fill_bytes(dest),
43-
Self::MT(m) => m.fill_bytes(dest),
36+
fn next_u64(&mut self) -> u64 {
37+
match self {
38+
Self::Std(s) => s.next_u64(),
39+
Self::MT(m) => m.next_u64(),
40+
}
4441
}
45-
}
46-
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand::Error> {
47-
match self {
48-
Self::Std(s) => s.try_fill_bytes(dest),
49-
Self::MT(m) => m.try_fill_bytes(dest),
42+
fn fill_bytes(&mut self, dest: &mut [u8]) {
43+
match self {
44+
Self::Std(s) => s.fill_bytes(dest),
45+
Self::MT(m) => m.fill_bytes(dest),
46+
}
47+
}
48+
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand::Error> {
49+
match self {
50+
Self::Std(s) => s.try_fill_bytes(dest),
51+
Self::MT(m) => m.try_fill_bytes(dest),
52+
}
5053
}
5154
}
52-
}
5355

54-
#[pyclass(name = "Random")]
55-
#[derive(Debug)]
56-
struct PyRandom {
57-
rng: RefCell<PyRng>,
58-
}
59-
60-
impl PyValue for PyRandom {
61-
fn class(vm: &VirtualMachine) -> PyClassRef {
62-
vm.class("_random", "Random")
56+
#[pyclass(name = "Random")]
57+
#[derive(Debug)]
58+
struct PyRandom {
59+
rng: RefCell<PyRng>,
6360
}
64-
}
6561

66-
#[pyimpl(flags(BASETYPE))]
67-
impl PyRandom {
68-
#[pyslot(new)]
69-
fn new(cls: PyClassRef, vm: &VirtualMachine) -> PyResult<PyRef<Self>> {
70-
PyRandom {
71-
rng: RefCell::new(PyRng::default()),
62+
impl PyValue for PyRandom {
63+
fn class(vm: &VirtualMachine) -> PyClassRef {
64+
vm.class("_random", "Random")
7265
}
73-
.into_ref_with_type(vm, cls)
7466
}
7567

76-
#[pymethod]
77-
fn random(&self) -> f64 {
78-
mt19937::gen_res53(&mut *self.rng.borrow_mut())
79-
}
68+
#[pyimpl(flags(BASETYPE))]
69+
impl PyRandom {
70+
#[pyslot(new)]
71+
fn new(cls: PyClassRef, vm: &VirtualMachine) -> PyResult<PyRef<Self>> {
72+
PyRandom {
73+
rng: RefCell::new(PyRng::default()),
74+
}
75+
.into_ref_with_type(vm, cls)
76+
}
77+
78+
#[pymethod]
79+
fn random(&self) -> f64 {
80+
mt19937::gen_res53(&mut *self.rng.borrow_mut())
81+
}
8082

81-
#[pymethod]
82-
fn seed(&self, n: OptionalOption<PyIntRef>) {
83-
let new_rng = match n.flat_option() {
84-
None => PyRng::default(),
85-
Some(n) => {
86-
let (_, mut key) = n.as_bigint().abs().to_u32_digits();
87-
if cfg!(target_endian = "big") {
88-
key.reverse();
83+
#[pymethod]
84+
fn seed(&self, n: OptionalOption<PyIntRef>) {
85+
let new_rng = match n.flat_option() {
86+
None => PyRng::default(),
87+
Some(n) => {
88+
let (_, mut key) = n.as_bigint().abs().to_u32_digits();
89+
if cfg!(target_endian = "big") {
90+
key.reverse();
91+
}
92+
PyRng::MT(Box::new(mt19937::MT19937::new_with_slice_seed(&key)))
8993
}
90-
PyRng::MT(Box::new(mt19937::MT19937::new_with_slice_seed(&key)))
91-
}
92-
};
94+
};
9395

94-
*self.rng.borrow_mut() = new_rng;
95-
}
96+
*self.rng.borrow_mut() = new_rng;
97+
}
9698

97-
#[pymethod]
98-
fn getrandbits(&self, mut k: usize) -> BigInt {
99-
let mut rng = self.rng.borrow_mut();
99+
#[pymethod]
100+
fn getrandbits(&self, mut k: usize) -> BigInt {
101+
let mut rng = self.rng.borrow_mut();
100102

101-
let mut gen_u32 = |k| rng.next_u32() >> (32 - k) as u32;
103+
let mut gen_u32 = |k| rng.next_u32() >> (32 - k) as u32;
102104

103-
if k <= 32 {
104-
return gen_u32(k).into();
105-
}
105+
if k <= 32 {
106+
return gen_u32(k).into();
107+
}
106108

107-
let words = (k - 1) / 8 + 1;
108-
let mut wordarray = vec![0u32; words];
109+
let words = (k - 1) / 8 + 1;
110+
let mut wordarray = vec![0u32; words];
109111

110-
let it = wordarray.iter_mut();
111-
#[cfg(target_endian = "big")]
112-
let it = it.rev();
113-
for word in it {
114-
*word = gen_u32(k);
115-
k -= 32;
116-
}
112+
let it = wordarray.iter_mut();
113+
#[cfg(target_endian = "big")]
114+
let it = it.rev();
115+
for word in it {
116+
*word = gen_u32(k);
117+
k -= 32;
118+
}
117119

118-
BigInt::from_slice(Sign::NoSign, &wordarray)
120+
BigInt::from_slice(Sign::NoSign, &wordarray)
121+
}
119122
}
120123
}
121-
122-
pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
123-
let ctx = &vm.ctx;
124-
py_module!(vm, "_random", {
125-
"Random" => PyRandom::make_class(ctx),
126-
})
127-
}

0 commit comments

Comments
 (0)