Skip to content

Commit 8127d5b

Browse files
authored
Merge branch 'master' into griffin/improve/add-comments-5
2 parents 0e06bc5 + 7d80f12 commit 8127d5b

File tree

9 files changed

+117
-2
lines changed

9 files changed

+117
-2
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ jobs:
142142
args: nextest --workspace --all-features --lcov --output-path lcov.info --profile ci -vv
143143

144144
- name: Upload coverage to Codecov
145-
uses: codecov/[email protected].4
145+
uses: codecov/[email protected].5
146146
with:
147147
token: ${{ secrets.CODE_COV }}
148148
files: lcov.info

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

planglib/std/__private.pi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ use std::libc;
1010
use std::buf;
1111
use std::err;
1212
use std::thread;
13+
use std::rand;

planglib/std/libc.pi

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,10 @@ const O_CREAT:i32;
1515

1616

1717
pub fn LibC__memcpy(dest:*u8, src:*u8, n:u64) *u8;
18+
19+
/// `buf`: `*u8` - buffer to fill with random data
20+
/// `buflen`: `u64` - length of buffer(in bytes)
21+
/// `flags`: `u32` - flags to pass to getrandom syscall
22+
/// - `0`: `GRND_RANDOM` - use /dev/random
23+
/// - `1`: `GRND_NONBLOCK` - return EAGAIN if not enough entropy
24+
pub fn LibC__getrandom(buf:*u8, buflen:u64, flags:u32) i64;

planglib/std/rand.pi

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
use std::libc::*;
2+
use core::panic;
3+
pub fn randi64() i64 {
4+
let ret = 0;
5+
let ptr = unsafe_cast<u8>(&ret);
6+
// 生成的随机数存储在ptr,8 bytes,使用/dev/random
7+
// 0阻塞,1非阻塞
8+
LibC__getrandom(ptr, 8 as u64, 0 as u32);
9+
return ret;
10+
}
11+
12+
/// 生成 `[0, max)` 的随机数,`max` 必须大于 `0`,否则 `panic`
13+
pub fn randi64n(max: i64) i64 {
14+
panic::assert(max > 0);
15+
let ret = (randi64() as u64) % (max as u64);
16+
return ret as i64;
17+
}
18+
19+
/// 生成 `[min, max)` 的随机数,`min` 必须小于 `max`,否则 `panic`
20+
pub fn randi64r(min: i64, max: i64) i64 {
21+
panic::assert(min < max);
22+
let ret = randi64n(max - min) + min;
23+
return ret;
24+
}

test/main.pi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ use std::io;
3030
use std::cols::hashtable;
3131
use project1::test::inference;
3232
use project1::test::futuretest;
33+
use project1::test::rand;
3334

3435
use core::hash::pl_hash::*;
3536
// use std::cols::hashtable::new_hash_table;

test/test/rand.pi

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
use std::rand::*;
2+
use core::panic::*;
3+
pub fn test_rand() void {
4+
let r1 = randi64n(5);
5+
assert(r1 >= 0 && r1 < 5);
6+
let r2 = randi64r(2, 9);
7+
assert(r2 >= 2 && r2 < 9);
8+
return;
9+
}

vm/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ log = { version = "0.4", features = ["std"] }
1414
libc = "0.2"
1515
bytecount = "0.6.3"
1616
context = "3.0.0"
17+
[target.'cfg(windows)'.dependencies]
18+
winapi = { version = "0.3", features = ["winuser", "wincrypt"] }
1719

1820
[dev-dependencies]
1921
rand = "0.8"

vm/src/libcwrap/mod.rs

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#![allow(clippy::useless_conversion)]
22
use std::ffi::CString;
3-
3+
#[cfg(target_os = "windows")]
4+
extern crate winapi;
45
use internal_macro::is_runtime;
56

67
struct LibC {}
@@ -87,4 +88,73 @@ impl LibC {
8788
) -> *mut libc::c_void {
8889
unsafe { libc::memcpy(dest, src, n) }
8990
}
91+
92+
fn getrandom(
93+
buf: *mut libc::c_void,
94+
buflen: libc::size_t,
95+
flags: libc::c_uint,
96+
) -> libc::ssize_t {
97+
getrandom_inner(buf, buflen, flags)
98+
}
99+
}
100+
101+
#[cfg(target_os = "linux")]
102+
fn getrandom_inner(
103+
buf: *mut libc::c_void,
104+
buflen: libc::size_t,
105+
flags: libc::c_uint,
106+
) -> libc::ssize_t {
107+
unsafe { libc::syscall(libc::SYS_getrandom, buf, buflen, flags) as libc::ssize_t }
108+
}
109+
110+
#[cfg(target_os = "macos")]
111+
extern "C" {
112+
// Supported as of macOS 10.12+.
113+
fn getentropy(buf: *mut u8, size: libc::size_t) -> libc::c_int;
114+
}
115+
#[cfg(target_os = "macos")]
116+
fn getrandom_inner(
117+
buf: *mut libc::c_void,
118+
buflen: libc::size_t,
119+
_flags: libc::c_uint,
120+
) -> libc::ssize_t {
121+
unsafe {
122+
if getentropy(buf as *mut u8, buflen) == 0 {
123+
return buflen as libc::ssize_t;
124+
} else {
125+
return -1;
126+
}
127+
}
128+
}
129+
130+
#[cfg(target_os = "windows")]
131+
fn getrandom_inner(
132+
buf: *mut libc::c_void,
133+
buflen: libc::size_t,
134+
_flags: libc::c_uint,
135+
) -> libc::ssize_t {
136+
use core::ptr::null_mut;
137+
use winapi::um::wincrypt::{
138+
CryptAcquireContextA, CryptGenRandom, CryptReleaseContext, CRYPT_VERIFYCONTEXT, HCRYPTPROV,
139+
PROV_RSA_FULL,
140+
};
141+
let mut hcryptprov: HCRYPTPROV = 0;
142+
unsafe {
143+
if CryptAcquireContextA(
144+
&mut hcryptprov,
145+
null_mut(),
146+
null_mut(),
147+
PROV_RSA_FULL,
148+
CRYPT_VERIFYCONTEXT,
149+
) == 0
150+
{
151+
return -1;
152+
}
153+
if CryptGenRandom(hcryptprov, buflen as u32, buf as *mut u8) == 0 {
154+
CryptReleaseContext(hcryptprov, 0);
155+
return -1;
156+
}
157+
CryptReleaseContext(hcryptprov, 0);
158+
}
159+
0
90160
}

0 commit comments

Comments
 (0)