Skip to content

Commit bed54e0

Browse files
committed
Add some constants to native modules
1 parent 5ca0e9a commit bed54e0

File tree

8 files changed

+84
-23
lines changed

8 files changed

+84
-23
lines changed

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.

bytecode/src/bytecode.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,13 @@ impl Default for CodeFlags {
6565
}
6666
}
6767

68+
impl CodeFlags {
69+
pub const NAME_MAPPING: &'static [(&'static str, CodeFlags)] = &[
70+
("GENERATOR", CodeFlags::IS_GENERATOR),
71+
("COROUTINE", CodeFlags::IS_COROUTINE),
72+
];
73+
}
74+
6875
#[derive(Serialize, Debug, Deserialize, Clone, Copy, PartialEq, Eq, Hash)]
6976
pub struct Label(usize);
7077

vm/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ num-rational = "0.2.2"
3232
num-iter = "0.1.39"
3333
rand = "0.7"
3434
rand_distr = "0.2"
35+
getrandom = "0.1"
3536
log = "0.4"
3637
rustpython-derive = {path = "../derive", version = "0.1.1"}
3738
rustpython-parser = {path = "../parser", optional = true, version = "0.1.1"}

vm/src/obj/objcode.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@ impl PyCodeRef {
8686
fn co_name(self, _vm: &VirtualMachine) -> String {
8787
self.code.obj_name.clone()
8888
}
89+
90+
fn co_flags(self, _vm: &VirtualMachine) -> u8 {
91+
self.code.flags.bits()
92+
}
8993
}
9094

9195
pub fn init(context: &PyContext) {
@@ -99,5 +103,6 @@ pub fn init(context: &PyContext) {
99103
"co_firstlineno" => context.new_property(PyCodeRef::co_firstlineno),
100104
"co_kwonlyargcount" => context.new_property(PyCodeRef::co_kwonlyargcount),
101105
"co_name" => context.new_property(PyCodeRef::co_name),
106+
"co_flags" => context.new_property(PyCodeRef::co_flags),
102107
});
103108
}

vm/src/stdlib/dis.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
use crate::bytecode::CodeFlags;
12
use crate::obj::objcode::PyCodeRef;
2-
use crate::pyobject::{PyObjectRef, PyResult, TryFromObject};
3+
use crate::pyobject::{ItemProtocol, PyObjectRef, PyResult, TryFromObject};
34
use crate::vm::VirtualMachine;
45

56
fn dis_dis(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult {
@@ -17,11 +18,25 @@ fn dis_disassemble(co: PyObjectRef, vm: &VirtualMachine) -> PyResult {
1718
Ok(vm.get_none())
1819
}
1920

21+
fn dis_compiler_flag_names(vm: &VirtualMachine) -> PyObjectRef {
22+
let dict = vm.ctx.new_dict();
23+
for (name, flag) in CodeFlags::NAME_MAPPING {
24+
dict.set_item(
25+
&vm.ctx.new_int(flag.bits()),
26+
vm.ctx.new_str(name.to_string()),
27+
vm,
28+
)
29+
.unwrap();
30+
}
31+
dict.into_object()
32+
}
33+
2034
pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
2135
let ctx = &vm.ctx;
2236

2337
py_module!(vm, "dis", {
2438
"dis" => ctx.new_rustfunc(dis_dis),
25-
"disassemble" => ctx.new_rustfunc(dis_disassemble)
39+
"disassemble" => ctx.new_rustfunc(dis_disassemble),
40+
"COMPILER_FLAG_NAMES" => dis_compiler_flag_names(vm),
2641
})
2742
}

vm/src/stdlib/os.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1090,6 +1090,17 @@ pub fn os_ttyname(fd: i32, vm: &VirtualMachine) -> PyResult {
10901090
}
10911091
}
10921092

1093+
fn os_urandom(size: usize, vm: &VirtualMachine) -> PyResult<Vec<u8>> {
1094+
let mut buf = vec![0u8; size];
1095+
match getrandom::getrandom(&mut buf) {
1096+
Ok(()) => Ok(buf),
1097+
Err(e) => match e.raw_os_error() {
1098+
Some(errno) => Err(convert_io_error(vm, io::Error::from_raw_os_error(errno))),
1099+
None => Err(vm.new_os_error("Getting random failed".to_string())),
1100+
},
1101+
}
1102+
}
1103+
10931104
pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
10941105
let ctx = &vm.ctx;
10951106

@@ -1214,6 +1225,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
12141225
"getpid" => ctx.new_rustfunc(os_getpid),
12151226
"cpu_count" => ctx.new_rustfunc(os_cpu_count),
12161227
"_exit" => ctx.new_rustfunc(os_exit),
1228+
"urandom" => ctx.new_rustfunc(os_urandom),
12171229

12181230
"O_RDONLY" => ctx.new_int(libc::O_RDONLY),
12191231
"O_WRONLY" => ctx.new_int(libc::O_WRONLY),

vm/src/stdlib/select.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,11 @@ fn select_select(
135135
let (wlist, mut w) = seq2set(&wlist)?;
136136
let (xlist, mut x) = seq2set(&xlist)?;
137137

138+
if rlist.is_empty() && wlist.is_empty() && xlist.is_empty() {
139+
let empty = vm.ctx.new_list(vec![]);
140+
return Ok((empty.clone(), empty.clone(), empty));
141+
}
142+
138143
let nfds = [&mut r, &mut w, &mut x]
139144
.iter_mut()
140145
.filter_map(|set| set.highest())

vm/src/stdlib/socket.rs

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use byteorder::{BigEndian, ByteOrder};
77
use gethostname::gethostname;
88
#[cfg(all(unix, not(target_os = "redox")))]
99
use nix::unistd::sethostname;
10-
use socket2::{Domain, Socket, Type as SocketType};
10+
use socket2::{Domain, Protocol, Socket, Type as SocketType};
1111

1212
use super::os::convert_io_error;
1313
#[cfg(unix)]
@@ -27,7 +27,31 @@ type RawSocket = std::os::unix::io::RawFd;
2727
type RawSocket = std::os::windows::raw::SOCKET;
2828

2929
#[cfg(unix)]
30-
use libc as c;
30+
mod c {
31+
pub use libc::*;
32+
// TODO: open a PR to add these constants to libc; then just use libc
33+
#[cfg(target_os = "android")]
34+
pub const AI_PASSIVE: c_int = 0x00000001;
35+
#[cfg(target_os = "android")]
36+
pub const AI_CANONNAME: c_int = 0x00000002;
37+
#[cfg(target_os = "android")]
38+
pub const AI_NUMERICHOST: c_int = 0x00000004;
39+
#[cfg(target_os = "android")]
40+
pub const AI_NUMERICSERV: c_int = 0x00000008;
41+
#[cfg(target_os = "android")]
42+
pub const AI_MASK: c_int =
43+
AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST | AI_NUMERICSERV | AI_ADDRCONFIG;
44+
#[cfg(target_os = "android")]
45+
pub const AI_ALL: c_int = 0x00000100;
46+
#[cfg(target_os = "android")]
47+
pub const AI_V4MAPPED_CFG: c_int = 0x00000200;
48+
#[cfg(target_os = "android")]
49+
pub const AI_ADDRCONFIG: c_int = 0x00000400;
50+
#[cfg(target_os = "android")]
51+
pub const AI_V4MAPPED: c_int = 0x00000800;
52+
#[cfg(target_os = "android")]
53+
pub const AI_DEFAULT: c_int = AI_V4MAPPED_CFG | AI_ADDRCONFIG;
54+
}
3155
#[cfg(windows)]
3256
mod c {
3357
pub use winapi::shared::ws2def::*;
@@ -92,28 +116,17 @@ impl PySocket {
92116
unsafe { Socket::from_raw_socket(fileno) }
93117
}
94118
} else {
95-
let domain = match family {
96-
c::AF_INET => Domain::ipv4(),
97-
c::AF_INET6 => Domain::ipv6(),
98-
#[cfg(unix)]
99-
c::AF_UNIX => Domain::unix(),
100-
_ => {
101-
return Err(vm.new_os_error(format!("Unknown address family value: {}", family)))
102-
}
103-
};
119+
let sock = Socket::new(
120+
Domain::from(family),
121+
SocketType::from(socket_kind),
122+
Some(Protocol::from(proto)),
123+
)
124+
.map_err(|err| convert_sock_error(vm, err))?;
125+
104126
self.family.set(family);
105-
let socket_type = match socket_kind {
106-
c::SOCK_STREAM => SocketType::stream(),
107-
c::SOCK_DGRAM => SocketType::dgram(),
108-
_ => {
109-
return Err(
110-
vm.new_os_error(format!("Unknown socket kind value: {}", socket_kind))
111-
)
112-
}
113-
};
114127
self.kind.set(socket_kind);
115128
self.proto.set(proto);
116-
Socket::new(domain, socket_type, None).map_err(|err| convert_sock_error(vm, err))?
129+
sock
117130
};
118131
self.sock.replace(sock);
119132
Ok(())
@@ -435,6 +448,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
435448
"error" => ctx.exceptions.os_error.clone(),
436449
"timeout" => socket_timeout,
437450
"gaierror" => socket_gaierror,
451+
"AF_UNSPEC" => ctx.new_int(0),
438452
"AF_INET" => ctx.new_int(c::AF_INET),
439453
"AF_INET6" => ctx.new_int(c::AF_INET6),
440454
"SOCK_STREAM" => ctx.new_int(c::SOCK_STREAM),
@@ -446,6 +460,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
446460
"MSG_PEEK" => ctx.new_int(c::MSG_PEEK),
447461
"MSG_WAITALL" => ctx.new_int(c::MSG_WAITALL),
448462
"AI_ALL" => ctx.new_int(c::AI_ALL),
463+
"AI_PASSIVE" => ctx.new_int(c::AI_PASSIVE),
449464
"socket" => PySocket::make_class(ctx),
450465
"inet_aton" => ctx.new_rustfunc(socket_inet_aton),
451466
"inet_ntoa" => ctx.new_rustfunc(socket_inet_ntoa),

0 commit comments

Comments
 (0)