mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-02 19:39:49 +09:00
Use cfg_select in a bunch more places (#7740)
This commit is contained in:
@@ -1,12 +1,7 @@
|
||||
#[cfg(not(feature = "threading"))]
|
||||
use alloc::rc::Rc;
|
||||
#[cfg(feature = "threading")]
|
||||
use alloc::sync::Arc;
|
||||
|
||||
// type aliases instead of new-types because you can't do `fn method(self: PyRc<Self>)` with a
|
||||
// newtype; requires the arbitrary_self_types unstable feature
|
||||
|
||||
#[cfg(feature = "threading")]
|
||||
pub type PyRc<T> = Arc<T>;
|
||||
#[cfg(not(feature = "threading"))]
|
||||
pub type PyRc<T> = Rc<T>;
|
||||
pub type PyRc<T> = cfg_select! {
|
||||
feature = "threading" => alloc::sync::Arc::<T>,
|
||||
_ => alloc::rc::Rc::<T>,
|
||||
};
|
||||
|
||||
@@ -20,10 +20,10 @@ const WEAK_COUNT: usize = 1 << STRONG_WIDTH;
|
||||
reason = "refcount overflow must preserve upstream abort semantics"
|
||||
)]
|
||||
fn refcount_overflow() -> ! {
|
||||
#[cfg(feature = "std")]
|
||||
std::process::abort();
|
||||
#[cfg(not(feature = "std"))]
|
||||
core::panic!("refcount overflow");
|
||||
cfg_select! {
|
||||
feature = "std" => std::process::abort(),
|
||||
_ => core::panic!("refcount overflow"),
|
||||
}
|
||||
}
|
||||
|
||||
/// State wraps reference count + flags in a single word (platform usize)
|
||||
|
||||
@@ -7,12 +7,11 @@ use core::fmt;
|
||||
use core::ops::{Bound, RangeBounds};
|
||||
use core::sync::atomic::Ordering::Relaxed;
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[allow(non_camel_case_types)]
|
||||
pub type wchar_t = libc::wchar_t;
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[allow(non_camel_case_types)]
|
||||
pub type wchar_t = u32;
|
||||
pub type wchar_t = cfg_select! {
|
||||
target_arch = "wasm32" => u32,
|
||||
_ => libc::wchar_t,
|
||||
};
|
||||
|
||||
/// Utf8 + state.ascii (+ PyUnicode_Kind in future)
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
|
||||
@@ -26,15 +26,15 @@ mod c {
|
||||
|
||||
// this is basically what CPython has for Py_off_t; windows uses long long
|
||||
// for offsets, other platforms just use off_t
|
||||
#[cfg(not(windows))]
|
||||
pub type Offset = c::off_t;
|
||||
#[cfg(windows)]
|
||||
pub type Offset = c::c_longlong;
|
||||
pub type Offset = cfg_select! {
|
||||
windows => c::c_longlong,
|
||||
_ => c::off_t,
|
||||
};
|
||||
|
||||
#[cfg(not(windows))]
|
||||
pub type Raw = RawFd;
|
||||
#[cfg(windows)]
|
||||
pub type Raw = i32;
|
||||
pub type Raw = cfg_select! {
|
||||
windows => i32,
|
||||
_ => RawFd,
|
||||
};
|
||||
|
||||
#[inline]
|
||||
fn cvt<I: num_traits::PrimInt>(ret: I) -> io::Result<I> {
|
||||
@@ -351,18 +351,16 @@ pub fn ftruncate(fd: Borrowed<'_>, len: Offset) -> io::Result<()> {
|
||||
let ret = unsafe { suppress_iph!(c::ftruncate(fd.as_raw(), len)) };
|
||||
// On Windows, _chsize_s returns 0 on success, or a positive error code (errno value) on failure.
|
||||
// On other platforms, ftruncate returns 0 on success, or -1 on failure with errno set.
|
||||
#[cfg(windows)]
|
||||
{
|
||||
if ret != 0 {
|
||||
// _chsize_s returns errno directly, convert to Windows error code
|
||||
let winerror = crate::os::errno_to_winerror(ret);
|
||||
return Err(io::Error::from_raw_os_error(winerror));
|
||||
cfg_select! {
|
||||
windows => {
|
||||
if ret != 0 {
|
||||
// _chsize_s returns errno directly, convert to Windows error code
|
||||
let winerror = crate::os::errno_to_winerror(ret);
|
||||
return Err(io::Error::from_raw_os_error(winerror));
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(not(windows))]
|
||||
{
|
||||
cvt(ret)?;
|
||||
}
|
||||
_ => cvt(ret)?,
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -119,30 +119,12 @@ mod decl {
|
||||
// PUTS macro
|
||||
#[cfg(any(unix, windows))]
|
||||
fn puts(fd: i32, s: &str) {
|
||||
let _ = unsafe {
|
||||
#[cfg(windows)]
|
||||
{
|
||||
libc::write(fd, s.as_ptr() as *const libc::c_void, s.len() as u32)
|
||||
}
|
||||
#[cfg(not(windows))]
|
||||
{
|
||||
libc::write(fd, s.as_ptr() as *const libc::c_void, s.len())
|
||||
}
|
||||
};
|
||||
puts_bytes(fd, s.as_bytes())
|
||||
}
|
||||
|
||||
#[cfg(any(unix, windows))]
|
||||
fn puts_bytes(fd: i32, s: &[u8]) {
|
||||
let _ = unsafe {
|
||||
#[cfg(windows)]
|
||||
{
|
||||
libc::write(fd, s.as_ptr() as *const libc::c_void, s.len() as u32)
|
||||
}
|
||||
#[cfg(not(windows))]
|
||||
{
|
||||
libc::write(fd, s.as_ptr() as *const libc::c_void, s.len())
|
||||
}
|
||||
};
|
||||
let _ = unsafe { libc::write(fd, s.as_ptr().cast::<libc::c_void>(), s.len() as _) };
|
||||
}
|
||||
|
||||
// _Py_DumpHexadecimal (traceback.c)
|
||||
@@ -158,16 +140,7 @@ mod decl {
|
||||
buf[2 + i] = HEX_CHARS[digit];
|
||||
}
|
||||
|
||||
let _ = unsafe {
|
||||
#[cfg(windows)]
|
||||
{
|
||||
libc::write(fd, buf.as_ptr() as *const libc::c_void, (2 + width) as u32)
|
||||
}
|
||||
#[cfg(not(windows))]
|
||||
{
|
||||
libc::write(fd, buf.as_ptr() as *const libc::c_void, 2 + width)
|
||||
}
|
||||
};
|
||||
puts_bytes(fd, &buf[..2 + width]);
|
||||
}
|
||||
|
||||
// _Py_DumpDecimal (traceback.c)
|
||||
@@ -188,17 +161,7 @@ mod decl {
|
||||
v /= 10;
|
||||
}
|
||||
|
||||
let len = buf.len() - i;
|
||||
let _ = unsafe {
|
||||
#[cfg(windows)]
|
||||
{
|
||||
libc::write(fd, buf[i..].as_ptr() as *const libc::c_void, len as u32)
|
||||
}
|
||||
#[cfg(not(windows))]
|
||||
{
|
||||
libc::write(fd, buf[i..].as_ptr() as *const libc::c_void, len)
|
||||
}
|
||||
};
|
||||
puts_bytes(fd, &buf[i..]);
|
||||
}
|
||||
|
||||
/// Get current thread ID
|
||||
@@ -857,30 +820,31 @@ mod decl {
|
||||
drop(guard); // Release lock before I/O
|
||||
|
||||
// Timeout occurred, dump traceback
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
let _ = (exit, fd, &header);
|
||||
cfg_select! {
|
||||
target_arch = "wasm32" => {
|
||||
let _ = (exit, fd, &header);
|
||||
}
|
||||
_ => {
|
||||
puts_bytes(fd, header.as_bytes());
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
{
|
||||
puts_bytes(fd, header.as_bytes());
|
||||
|
||||
// Use thread frame slots when threading is enabled (includes all threads).
|
||||
// Fall back to live frame walking for non-threaded builds.
|
||||
#[cfg(feature = "threading")]
|
||||
{
|
||||
for (tid, slot) in &thread_frame_slots {
|
||||
let frames = slot.frames.lock();
|
||||
dump_traceback_thread_frames(fd, *tid, false, &frames);
|
||||
// Use thread frame slots when threading is enabled (includes all threads).
|
||||
// Fall back to live frame walking for non-threaded builds.
|
||||
cfg_select! {
|
||||
feature = "threading" => {
|
||||
for (tid, slot) in &thread_frame_slots {
|
||||
let frames = slot.frames.lock();
|
||||
dump_traceback_thread_frames(fd, *tid, false, &frames);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
write_thread_id(fd, current_thread_id(), false);
|
||||
dump_live_frames(fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(not(feature = "threading"))]
|
||||
{
|
||||
write_thread_id(fd, current_thread_id(), false);
|
||||
dump_live_frames(fd);
|
||||
}
|
||||
|
||||
if exit {
|
||||
rustpython_host_env::os::exit(1);
|
||||
if exit {
|
||||
rustpython_host_env::os::exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1307,15 +1307,13 @@ mod _ssl {
|
||||
#[pygetset]
|
||||
fn num_tickets(&self, _vm: &VirtualMachine) -> PyResult<usize> {
|
||||
// Only supported for TLS 1.3
|
||||
#[cfg(ossl110)]
|
||||
{
|
||||
let ctx = self.ctx();
|
||||
let num = unsafe { sys::SSL_CTX_get_num_tickets(ctx.as_ptr()) };
|
||||
Ok(num)
|
||||
}
|
||||
#[cfg(not(ossl110))]
|
||||
{
|
||||
Ok(0)
|
||||
cfg_select! {
|
||||
ossl111 => {
|
||||
let ctx = self.ctx();
|
||||
let num = unsafe { sys::SSL_CTX_get_num_tickets(ctx.as_ptr()) };
|
||||
Ok(num)
|
||||
}
|
||||
_ => Ok(0),
|
||||
}
|
||||
}
|
||||
#[pygetset(setter)]
|
||||
@@ -1330,19 +1328,19 @@ mod _ssl {
|
||||
return Err(vm.new_value_error("SSLContext is not a server context."));
|
||||
}
|
||||
|
||||
#[cfg(ossl110)]
|
||||
{
|
||||
let ctx = self.builder();
|
||||
let result = unsafe { sys::SSL_CTX_set_num_tickets(ctx.as_ptr(), value as usize) };
|
||||
if result != 1 {
|
||||
return Err(vm.new_value_error("failed to set num tickets."));
|
||||
cfg_select! {
|
||||
ossl110 => {
|
||||
let ctx = self.builder();
|
||||
let result = unsafe { sys::SSL_CTX_set_num_tickets(ctx.as_ptr(), value as usize) };
|
||||
if result != 1 {
|
||||
return Err(vm.new_value_error("failed to set num tickets."));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
_ => {
|
||||
let _ = (value, vm);
|
||||
Ok(())
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
#[cfg(not(ossl110))]
|
||||
{
|
||||
let _ = (value, vm);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1564,10 +1562,10 @@ mod _ssl {
|
||||
) -> PyResult<Vec<PyObjectRef>> {
|
||||
let binary_form = args.binary_form.unwrap_or(false);
|
||||
let ctx = self.ctx();
|
||||
#[cfg(ossl300)]
|
||||
let certs = ctx.cert_store().all_certificates();
|
||||
#[cfg(not(ossl300))]
|
||||
let certs = ctx.cert_store().objects().iter().filter_map(|x| x.x509());
|
||||
let certs = cfg_select! {
|
||||
ossl300 => ctx.cert_store().all_certificates(),
|
||||
_ => ctx.cert_store().objects().iter().filter_map(|x| x.x509()),
|
||||
};
|
||||
|
||||
// Filter to only include CA certificates (Basic Constraints: CA=TRUE)
|
||||
let certs = certs
|
||||
@@ -2792,21 +2790,21 @@ mod _ssl {
|
||||
|
||||
#[pymethod]
|
||||
fn verify_client_post_handshake(&self, vm: &VirtualMachine) -> PyResult<()> {
|
||||
#[cfg(ossl111)]
|
||||
{
|
||||
let stream = self.connection.read();
|
||||
let result = unsafe { SSL_verify_client_post_handshake(stream.ssl().as_ptr()) };
|
||||
if result == 0 {
|
||||
Err(convert_openssl_error(vm, openssl::error::ErrorStack::get()))
|
||||
} else {
|
||||
Ok(())
|
||||
cfg_select! {
|
||||
ossl111 => {
|
||||
let stream = self.connection.read();
|
||||
let result = unsafe { SSL_verify_client_post_handshake(stream.ssl().as_ptr()) };
|
||||
if result == 0 {
|
||||
Err(convert_openssl_error(vm, openssl::error::ErrorStack::get()))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
Err(vm.new_not_implemented_error(
|
||||
"Post-handshake auth is not supported by your OpenSSL version.",
|
||||
))
|
||||
}
|
||||
}
|
||||
#[cfg(not(ossl111))]
|
||||
{
|
||||
Err(vm.new_not_implemented_error(
|
||||
"Post-handshake auth is not supported by your OpenSSL version.",
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3681,15 +3679,9 @@ mod _ssl {
|
||||
impl PySslSession {
|
||||
#[pygetset]
|
||||
fn time(&self) -> i64 {
|
||||
unsafe {
|
||||
#[cfg(ossl330)]
|
||||
{
|
||||
sys::SSL_SESSION_get_time(self.session) as i64
|
||||
}
|
||||
#[cfg(not(ossl330))]
|
||||
{
|
||||
sys::SSL_SESSION_get_time(self.session) as i64
|
||||
}
|
||||
cfg_select! {
|
||||
ossl330 => unsafe { sys::SSL_SESSION_get_time(self.session) as i64 },
|
||||
_ => unsafe { sys::SSL_SESSION_get_time(self.session) as i64 },
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3701,14 +3693,10 @@ mod _ssl {
|
||||
#[pygetset]
|
||||
fn ticket_lifetime_hint(&self) -> u64 {
|
||||
// SSL_SESSION_get_ticket_lifetime_hint available in OpenSSL 1.1.0+
|
||||
#[cfg(ossl110)]
|
||||
{
|
||||
unsafe { SSL_SESSION_get_ticket_lifetime_hint(self.session) as u64 }
|
||||
}
|
||||
#[cfg(not(ossl110))]
|
||||
{
|
||||
cfg_select! {
|
||||
ossl110 => unsafe { SSL_SESSION_get_ticket_lifetime_hint(self.session) as u64 },
|
||||
// Not available in older OpenSSL versions
|
||||
0
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3725,14 +3713,10 @@ mod _ssl {
|
||||
#[pygetset]
|
||||
fn has_ticket(&self) -> bool {
|
||||
// SSL_SESSION_has_ticket available in OpenSSL 1.1.0+
|
||||
#[cfg(ossl110)]
|
||||
{
|
||||
unsafe { SSL_SESSION_has_ticket(self.session) != 0 }
|
||||
}
|
||||
#[cfg(not(ossl110))]
|
||||
{
|
||||
cfg_select! {
|
||||
ossl110 => unsafe { SSL_SESSION_has_ticket(self.session) != 0 },
|
||||
// Not available in older OpenSSL versions
|
||||
false
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3273,7 +3273,7 @@ mod _socket {
|
||||
fn sock_from_raw(fileno: RawSocket, vm: &VirtualMachine) -> PyResult<Socket> {
|
||||
let invalid = cfg_select! {
|
||||
windows => fileno == INVALID_SOCKET,
|
||||
_ => fileno < 0
|
||||
_ => fileno < 0,
|
||||
};
|
||||
if invalid {
|
||||
return Err(vm.new_value_error("negative file descriptor"));
|
||||
|
||||
@@ -4832,31 +4832,20 @@ mod _ssl {
|
||||
|
||||
// Common default paths for different platforms
|
||||
// These match the first candidates that rustls-native-certs/openssl-probe checks
|
||||
#[cfg(target_os = "macos")]
|
||||
let (default_cafile, default_capath) = {
|
||||
let (default_cafile, default_capath): (Option<&str>, Option<&str>) = cfg_select! {
|
||||
// macOS primarily uses Keychain API, but provides fallback paths
|
||||
// for compatibility and when Keychain access fails
|
||||
(Some("/etc/ssl/cert.pem"), Some("/etc/ssl/certs"))
|
||||
};
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
let (default_cafile, default_capath) = {
|
||||
target_os = "macos" => (Some("/etc/ssl/cert.pem"), Some("/etc/ssl/certs")),
|
||||
// Linux: matches openssl-probe's first candidate (/etc/ssl/cert.pem)
|
||||
// openssl-probe checks multiple locations at runtime, but we return
|
||||
// OpenSSL's compile-time default
|
||||
(Some("/etc/ssl/cert.pem"), Some("/etc/ssl/certs"))
|
||||
};
|
||||
|
||||
#[cfg(windows)]
|
||||
let (default_cafile, default_capath) = {
|
||||
target_os = "linux" => (Some("/etc/ssl/cert.pem"), Some("/etc/ssl/certs")),
|
||||
// Windows uses certificate store, not file paths
|
||||
// Return empty strings to avoid None being passed to os.path.isfile()
|
||||
(Some(""), Some(""))
|
||||
windows => (Some(""), Some("")),
|
||||
_ => (None, None),
|
||||
};
|
||||
|
||||
#[cfg(not(any(target_os = "macos", target_os = "linux", windows)))]
|
||||
let (default_cafile, default_capath): (Option<&str>, Option<&str>) = (None, None);
|
||||
|
||||
let tuple = vm.ctx.new_tuple(vec![
|
||||
vm.ctx.new_str("SSL_CERT_FILE").into(), // openssl_cafile_env
|
||||
default_cafile
|
||||
|
||||
@@ -61,10 +61,10 @@ impl ByteOrder for LittleEndian {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_endian = "big")]
|
||||
type NativeEndian = BigEndian;
|
||||
#[cfg(target_endian = "little")]
|
||||
type NativeEndian = LittleEndian;
|
||||
type NativeEndian = cfg_select! {
|
||||
target_endian = "big" => BigEndian,
|
||||
target_endian = "little" => LittleEndian,
|
||||
};
|
||||
|
||||
#[derive(Copy, Clone, num_enum::TryFromPrimitive)]
|
||||
#[repr(u8)]
|
||||
|
||||
@@ -441,15 +441,15 @@ enum StandardEncoding {
|
||||
}
|
||||
|
||||
impl StandardEncoding {
|
||||
#[cfg(target_endian = "little")]
|
||||
const UTF_16_NE: Self = Self::Utf16Le;
|
||||
#[cfg(target_endian = "big")]
|
||||
const UTF_16_NE: Self = Self::Utf16Be;
|
||||
const UTF_16_NE: Self = cfg_select! {
|
||||
target_endian = "little" => Self::Utf16Le,
|
||||
target_endian = "big" => Self::Utf16Be,
|
||||
};
|
||||
|
||||
#[cfg(target_endian = "little")]
|
||||
const UTF_32_NE: Self = Self::Utf32Le;
|
||||
#[cfg(target_endian = "big")]
|
||||
const UTF_32_NE: Self = Self::Utf32Be;
|
||||
const UTF_32_NE: Self = cfg_select! {
|
||||
target_endian = "little" => Self::Utf32Le,
|
||||
target_endian = "big" => Self::Utf32Be,
|
||||
};
|
||||
|
||||
fn parse(encoding: &str) -> Option<Self> {
|
||||
if let Some(encoding) = encoding.to_lowercase().strip_prefix("utf") {
|
||||
|
||||
@@ -1354,10 +1354,10 @@ impl OSErrorBuilder {
|
||||
} = self;
|
||||
|
||||
let args = if let Some(errno) = errno {
|
||||
#[cfg(windows)]
|
||||
let winerror = winerror.to_pyobject(vm);
|
||||
#[cfg(not(windows))]
|
||||
let winerror = vm.ctx.none();
|
||||
let winerror = cfg_select! {
|
||||
windows => winerror.to_pyobject(vm),
|
||||
_ => vm.ctx.none(),
|
||||
};
|
||||
|
||||
vec![
|
||||
errno.to_pyobject(vm),
|
||||
@@ -2089,21 +2089,19 @@ pub(super) mod types {
|
||||
.get_attr("filename2", vm)
|
||||
.ok()
|
||||
.filter(|f| !vm.is_none(f));
|
||||
#[cfg(windows)]
|
||||
let winerror = obj.get_attr("winerror", vm).ok().filter(|w| !vm.is_none(w));
|
||||
|
||||
let winerror: Option<PyObjectRef> = cfg_select! {
|
||||
windows => obj.get_attr("winerror", vm).ok().filter(|w| !vm.is_none(w)),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
if let Some(filename2) = filename2 {
|
||||
#[cfg(windows)]
|
||||
{
|
||||
args_reduced.push(winerror.unwrap_or_else(|| vm.ctx.none()));
|
||||
}
|
||||
#[cfg(not(windows))]
|
||||
args_reduced.push(vm.ctx.none());
|
||||
args_reduced.push(filename2);
|
||||
#[allow(clippy::unnecessary_literal_unwrap)]
|
||||
let winerror = winerror.unwrap_or_else(|| vm.ctx.none());
|
||||
args_reduced.extend([winerror, filename2]);
|
||||
} else {
|
||||
// Diverges from CPython: include winerror even without
|
||||
// filename2 so it survives pickle round-trips.
|
||||
#[cfg(windows)]
|
||||
if let Some(winerror) = winerror {
|
||||
args_reduced.push(winerror);
|
||||
}
|
||||
|
||||
@@ -307,11 +307,10 @@ fn calculate_base_executable(executable: Option<&PathBuf>, home_dir: &Option<Pat
|
||||
/// Calculate stdlib_dir (sys._stdlib_dir)
|
||||
/// Returns None if the stdlib directory doesn't exist
|
||||
fn calculate_stdlib_dir(prefix: &str) -> Option<String> {
|
||||
#[cfg(not(windows))]
|
||||
let stdlib_dir = PathBuf::from(prefix).join(platform::stdlib_subdir());
|
||||
|
||||
#[cfg(windows)]
|
||||
let stdlib_dir = PathBuf::from(prefix).join(platform::STDLIB_SUBDIR);
|
||||
let stdlib_dir = Path::new(prefix).join(cfg_select! {
|
||||
windows => platform::STDLIB_SUBDIR,
|
||||
_ => platform::stdlib_subdir(),
|
||||
});
|
||||
|
||||
if stdlib_dir.is_dir() {
|
||||
Some(stdlib_dir.to_string_lossy().into_owned())
|
||||
|
||||
@@ -655,24 +655,24 @@ fn wstring_at_impl(ptr: usize, size: isize, vm: &VirtualMachine) -> PyResult {
|
||||
|
||||
// Windows: wchar_t = u16 (UTF-16) -> use Wtf8Buf::from_wide
|
||||
// macOS/Linux: wchar_t = i32 (UTF-32) -> convert via char::from_u32
|
||||
#[cfg(windows)]
|
||||
{
|
||||
use rustpython_common::wtf8::Wtf8Buf;
|
||||
let wide: Vec<u16> = wchars.to_vec();
|
||||
let wtf8 = Wtf8Buf::from_wide(&wide);
|
||||
Ok(vm.ctx.new_str(wtf8).into())
|
||||
}
|
||||
#[cfg(not(windows))]
|
||||
{
|
||||
#[allow(
|
||||
clippy::useless_conversion,
|
||||
reason = "wchar_t is i32 on some platforms and u32 on others"
|
||||
)]
|
||||
let s: String = wchars
|
||||
.iter()
|
||||
.filter_map(|&c| u32::try_from(c).ok().and_then(char::from_u32))
|
||||
.collect();
|
||||
Ok(vm.ctx.new_str(s).into())
|
||||
cfg_select! {
|
||||
windows => {
|
||||
use rustpython_common::wtf8::Wtf8Buf;
|
||||
let wide: Vec<u16> = wchars.to_vec();
|
||||
let wtf8 = Wtf8Buf::from_wide(&wide);
|
||||
Ok(vm.ctx.new_str(wtf8).into())
|
||||
}
|
||||
_ => {
|
||||
#[allow(
|
||||
clippy::useless_conversion,
|
||||
reason = "wchar_t is i32 on some platforms and u32 on others"
|
||||
)]
|
||||
let s: String = wchars
|
||||
.iter()
|
||||
.filter_map(|&c| u32::try_from(c).ok().and_then(char::from_u32))
|
||||
.collect();
|
||||
Ok(vm.ctx.new_str(s).into())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2027,24 +2027,24 @@ fn ffi_to_python(ty: &Py<PyType>, ptr: *const c_void, vm: &VirtualMachine) -> Py
|
||||
let slice = core::slice::from_raw_parts(wstr_ptr, len);
|
||||
// Windows: wchar_t = u16 (UTF-16) -> use Wtf8Buf::from_wide
|
||||
// Unix: wchar_t = i32 (UTF-32) -> convert via char::from_u32
|
||||
#[cfg(windows)]
|
||||
{
|
||||
use rustpython_common::wtf8::Wtf8Buf;
|
||||
let wide: Vec<u16> = slice.to_vec();
|
||||
let wtf8 = Wtf8Buf::from_wide(&wide);
|
||||
vm.ctx.new_str(wtf8).into()
|
||||
}
|
||||
#[cfg(not(windows))]
|
||||
{
|
||||
#[allow(
|
||||
clippy::useless_conversion,
|
||||
reason = "wchar_t is i32 on some platforms and u32 on others"
|
||||
)]
|
||||
let s: String = slice
|
||||
.iter()
|
||||
.filter_map(|&c| u32::try_from(c).ok().and_then(char::from_u32))
|
||||
.collect();
|
||||
vm.ctx.new_str(s).into()
|
||||
cfg_select! {
|
||||
windows => {
|
||||
use rustpython_common::wtf8::Wtf8Buf;
|
||||
let wide: Vec<u16> = slice.to_vec();
|
||||
let wtf8 = Wtf8Buf::from_wide(&wide);
|
||||
vm.ctx.new_str(wtf8).into()
|
||||
}
|
||||
_ => {
|
||||
#[allow(
|
||||
clippy::useless_conversion,
|
||||
reason = "wchar_t is i32 on some platforms and u32 on others"
|
||||
)]
|
||||
let s: String = slice
|
||||
.iter()
|
||||
.filter_map(|&c| u32::try_from(c).ok().and_then(char::from_u32))
|
||||
.collect();
|
||||
vm.ctx.new_str(s).into()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,12 +18,12 @@ use core::fmt::Debug;
|
||||
use num_traits::ToPrimitive;
|
||||
|
||||
/// Valid type codes for ctypes simple types
|
||||
#[cfg(windows)]
|
||||
// spell-checker: disable-next-line
|
||||
pub(super) const SIMPLE_TYPE_CHARS: &str = "cbBhHiIlLdfuzZqQPXOv?g";
|
||||
#[cfg(not(windows))]
|
||||
// spell-checker: disable-next-line
|
||||
pub(super) const SIMPLE_TYPE_CHARS: &str = "cbBhHiIlLdfuzZqQPOv?g";
|
||||
pub(super) const SIMPLE_TYPE_CHARS: &str = cfg_select! {
|
||||
// spell-checker: disable-next-line
|
||||
windows => "cbBhHiIlLdfuzZqQPXOv?g",
|
||||
// spell-checker: disable-next-line
|
||||
_ => "cbBhHiIlLdfuzZqQPOv?g",
|
||||
};
|
||||
|
||||
/// Convert ctypes type code to PEP 3118 format code.
|
||||
/// Some ctypes codes need to be mapped to standard-size codes based on platform.
|
||||
|
||||
@@ -152,7 +152,7 @@ mod _io {
|
||||
any(target_os = "dragonfly", target_os = "freebsd", target_os = "linux") => {
|
||||
x || matches!(whence, libc::SEEK_DATA | libc::SEEK_HOLE)
|
||||
}
|
||||
_ => x
|
||||
_ => x,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5096,23 +5096,23 @@ mod _io {
|
||||
// Construct a RawIO (subclass of RawIOBase)
|
||||
// On Windows, use _WindowsConsoleIO for console handles.
|
||||
// This is subsequently consumed by a Buffered Class.
|
||||
#[cfg(all(feature = "host_env", windows))]
|
||||
let is_console = super::winconsoleio::pyio_get_console_type(&file, vm) != '\0';
|
||||
#[cfg(not(all(feature = "host_env", windows)))]
|
||||
let is_console = false;
|
||||
|
||||
let file_io_class: &Py<PyType> = {
|
||||
cfg_select! {
|
||||
all(feature = "host_env", windows) => {
|
||||
if is_console {
|
||||
Some(super::winconsoleio::WindowsConsoleIO::static_type())
|
||||
} else {
|
||||
Some(super::fileio::FileIO::static_type())
|
||||
}
|
||||
}
|
||||
feature = "host_env" => Some(super::fileio::FileIO::static_type()),
|
||||
_ => None,
|
||||
let is_console = cfg_select! {
|
||||
all(feature = "host_env", windows) => {
|
||||
super::winconsoleio::pyio_get_console_type(&file, vm) != '\0'
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
|
||||
let file_io_class: &Py<PyType> = cfg_select! {
|
||||
all(feature = "host_env", windows) => {
|
||||
if is_console {
|
||||
Some(super::winconsoleio::WindowsConsoleIO::static_type())
|
||||
} else {
|
||||
Some(super::fileio::FileIO::static_type())
|
||||
}
|
||||
}
|
||||
feature = "host_env" => Some(super::fileio::FileIO::static_type()),
|
||||
_ => None,
|
||||
}
|
||||
.ok_or_else(|| {
|
||||
new_unsupported_operation(
|
||||
|
||||
@@ -16,11 +16,11 @@ pub(crate) mod _signal {
|
||||
#[cfg(unix)]
|
||||
use rustpython_host_env::signal::{double_to_timeval, itimerval_to_tuple};
|
||||
|
||||
#[cfg(any(unix, windows))]
|
||||
use libc::sighandler_t;
|
||||
#[allow(non_camel_case_types)]
|
||||
#[cfg(not(any(unix, windows)))]
|
||||
type sighandler_t = usize;
|
||||
type sighandler_t = cfg_select! {
|
||||
any(unix, windows) => libc::sighandler_t,
|
||||
_ => usize,
|
||||
};
|
||||
|
||||
cfg_select! {
|
||||
windows => {
|
||||
@@ -558,40 +558,39 @@ pub(crate) mod _signal {
|
||||
use crate::PyPayload;
|
||||
use crate::builtins::PySet;
|
||||
let set = PySet::default().into_ref(&vm.ctx);
|
||||
#[cfg(unix)]
|
||||
{
|
||||
// Use sigfillset to get all valid signals
|
||||
let mut mask: libc::sigset_t = unsafe { core::mem::zeroed() };
|
||||
// SAFETY: mask is a valid pointer
|
||||
if unsafe { libc::sigfillset(&mut mask) } != 0 {
|
||||
return Err(vm.new_os_error("sigfillset failed".to_owned()));
|
||||
}
|
||||
// Convert the filled mask to a Python set
|
||||
for signum in 1..signal::NSIG {
|
||||
if unsafe { libc::sigismember(&mask, signum as i32) } == 1 {
|
||||
set.add(vm.ctx.new_int(signum as i32).into(), vm)?;
|
||||
cfg_select! {
|
||||
unix => {
|
||||
// Use sigfillset to get all valid signals
|
||||
let mut mask: libc::sigset_t = unsafe { core::mem::zeroed() };
|
||||
// SAFETY: mask is a valid pointer
|
||||
if unsafe { libc::sigfillset(&mut mask) } != 0 {
|
||||
return Err(vm.new_os_error("sigfillset failed".to_owned()));
|
||||
}
|
||||
// Convert the filled mask to a Python set
|
||||
for signum in 1..signal::NSIG {
|
||||
if unsafe { libc::sigismember(&mask, signum as i32) } == 1 {
|
||||
set.add(vm.ctx.new_int(signum as i32).into(), vm)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(windows)]
|
||||
{
|
||||
// Windows only supports a limited set of signals
|
||||
for &signum in &[
|
||||
libc::SIGINT,
|
||||
libc::SIGILL,
|
||||
libc::SIGFPE,
|
||||
libc::SIGSEGV,
|
||||
libc::SIGTERM,
|
||||
SIGBREAK,
|
||||
libc::SIGABRT,
|
||||
] {
|
||||
set.add(vm.ctx.new_int(signum).into(), vm)?;
|
||||
windows => {
|
||||
// Windows only supports a limited set of signals
|
||||
for &signum in &[
|
||||
libc::SIGINT,
|
||||
libc::SIGILL,
|
||||
libc::SIGFPE,
|
||||
libc::SIGSEGV,
|
||||
libc::SIGTERM,
|
||||
SIGBREAK,
|
||||
libc::SIGABRT,
|
||||
] {
|
||||
set.add(vm.ctx.new_int(signum).into(), vm)?;
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
// Empty set for platforms without signal support (e.g., WASM)
|
||||
let _ = &set;
|
||||
}
|
||||
}
|
||||
#[cfg(not(any(unix, windows)))]
|
||||
{
|
||||
// Empty set for platforms without signal support (e.g., WASM)
|
||||
let _ = &set;
|
||||
}
|
||||
Ok(set.into())
|
||||
}
|
||||
|
||||
@@ -824,10 +824,10 @@ pub(super) mod _os {
|
||||
.map_err(|e| e.into_pyexception(vm))?
|
||||
.ok_or_else(|| crate::exceptions::cstring_error(vm))?;
|
||||
// On Windows, combine st_ino and st_ino_high into 128-bit value
|
||||
#[cfg(windows)]
|
||||
let ino: u128 = stat.st_ino as u128 | ((stat.st_ino_high as u128) << 64);
|
||||
#[cfg(not(windows))]
|
||||
let ino: u128 = stat.st_ino as u128;
|
||||
let ino: u128 = cfg_select! {
|
||||
windows => stat.st_ino as u128 | ((stat.st_ino_high as u128) << 64),
|
||||
_ => stat.st_ino as u128,
|
||||
};
|
||||
// Err(T) means other thread set `ino` at the mean time which is safe to ignore
|
||||
let _ = self.ino.compare_exchange(None, Some(ino));
|
||||
Ok(ino)
|
||||
|
||||
@@ -491,24 +491,23 @@ pub mod decl {
|
||||
secs: OptionalArg<Option<Either<f64, i64>>>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<StructTimeData> {
|
||||
#[cfg(any(unix, windows))]
|
||||
{
|
||||
let ts = match secs {
|
||||
OptionalArg::Present(Some(value)) => pyobj_to_time_t(value, vm)?,
|
||||
OptionalArg::Present(None) | OptionalArg::Missing => current_time_t(),
|
||||
};
|
||||
gmtime_from_timestamp(ts, vm)
|
||||
}
|
||||
|
||||
#[cfg(not(any(unix, windows)))]
|
||||
{
|
||||
let instant = match secs {
|
||||
OptionalArg::Present(Some(secs)) => pyobj_to_date_time(secs, vm)?.naive_utc(),
|
||||
OptionalArg::Present(None) | OptionalArg::Missing => {
|
||||
chrono::offset::Utc::now().naive_utc()
|
||||
}
|
||||
};
|
||||
Ok(StructTimeData::new_utc(vm, instant))
|
||||
cfg_select! {
|
||||
any(unix, windows) => {
|
||||
let ts = match secs {
|
||||
OptionalArg::Present(Some(value)) => pyobj_to_time_t(value, vm)?,
|
||||
OptionalArg::Present(None) | OptionalArg::Missing => current_time_t(),
|
||||
};
|
||||
gmtime_from_timestamp(ts, vm)
|
||||
}
|
||||
_ => {
|
||||
let instant = match secs {
|
||||
OptionalArg::Present(Some(secs)) => pyobj_to_date_time(secs, vm)?.naive_utc(),
|
||||
OptionalArg::Present(None) | OptionalArg::Missing => {
|
||||
chrono::offset::Utc::now().naive_utc()
|
||||
}
|
||||
};
|
||||
Ok(StructTimeData::new_utc(vm, instant))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -517,20 +516,18 @@ pub mod decl {
|
||||
secs: OptionalArg<Option<Either<f64, i64>>>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<StructTimeData> {
|
||||
#[cfg(any(unix, windows))]
|
||||
{
|
||||
let ts = match secs {
|
||||
OptionalArg::Present(Some(value)) => pyobj_to_time_t(value, vm)?,
|
||||
OptionalArg::Present(None) | OptionalArg::Missing => current_time_t(),
|
||||
};
|
||||
localtime_from_timestamp(ts, vm)
|
||||
}
|
||||
|
||||
#[cfg(not(any(unix, windows)))]
|
||||
let instant = secs.naive_or_local(vm)?;
|
||||
#[cfg(not(any(unix, windows)))]
|
||||
{
|
||||
Ok(StructTimeData::new_local(vm, instant, 0))
|
||||
cfg_select! {
|
||||
any(unix, windows) => {
|
||||
let ts = match secs {
|
||||
OptionalArg::Present(Some(value)) => pyobj_to_time_t(value, vm)?,
|
||||
OptionalArg::Present(None) | OptionalArg::Missing => current_time_t(),
|
||||
};
|
||||
localtime_from_timestamp(ts, vm)
|
||||
}
|
||||
_ => {
|
||||
let instant = secs.naive_or_local(vm)?;
|
||||
Ok(StructTimeData::new_local(vm, instant, 0))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,20 +19,19 @@ pub const VERSION_HEX: usize =
|
||||
pub fn get_version() -> String {
|
||||
// Windows: include MSC v. for compatibility with ctypes.util.find_library
|
||||
// MSC v.1929 = VS 2019, version 14+ makes find_msvcrt() return None
|
||||
#[cfg(windows)]
|
||||
let msc_info = {
|
||||
let arch = if cfg!(target_pointer_width = "64") {
|
||||
"64 bit (AMD64)"
|
||||
} else {
|
||||
"32 bit (Intel)"
|
||||
};
|
||||
// Include both RustPython identifier and MSC v. for compatibility
|
||||
format!(" MSC v.1929 {arch}",)
|
||||
let msc_info = cfg_select! {
|
||||
windows => {{
|
||||
let arch = if cfg!(target_pointer_width = "64") {
|
||||
"64 bit (AMD64)"
|
||||
} else {
|
||||
"32 bit (Intel)"
|
||||
};
|
||||
// Include both RustPython identifier and MSC v. for compatibility
|
||||
format!(" MSC v.1929 {arch}",)
|
||||
}},
|
||||
_ => String::new(),
|
||||
};
|
||||
|
||||
#[cfg(not(windows))]
|
||||
let msc_info = String::new();
|
||||
|
||||
format!(
|
||||
"{:.80} ({:.80}) \n[RustPython {} with {:.80}{}]", // \n is PyPy convention
|
||||
get_version_number(),
|
||||
|
||||
@@ -699,13 +699,11 @@ impl VirtualMachine {
|
||||
/// Mirrors `_Py_ThreadCanHandleSignals`.
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn is_main_thread(&self) -> bool {
|
||||
#[cfg(feature = "threading")]
|
||||
{
|
||||
crate::stdlib::_thread::get_ident() == self.state.main_thread_ident.load()
|
||||
}
|
||||
#[cfg(not(feature = "threading"))]
|
||||
{
|
||||
true
|
||||
cfg_select! {
|
||||
feature = "threading" => {
|
||||
crate::stdlib::_thread::get_ident() == self.state.main_thread_ident.load()
|
||||
}
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2037,13 +2035,9 @@ impl VirtualMachine {
|
||||
thread::suspend_if_needed(&self.state.stop_the_world);
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
{
|
||||
crate::signal::check_signals(self)
|
||||
}
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
{
|
||||
Ok(())
|
||||
}
|
||||
crate::signal::check_signals(self)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Push a new exc_info slot (for generator/coroutine resume).
|
||||
@@ -2158,11 +2152,9 @@ impl VirtualMachine {
|
||||
}
|
||||
1
|
||||
} else if exc.fast_isinstance(self.ctx.exceptions.keyboard_interrupt) {
|
||||
#[allow(clippy::if_same_then_else)]
|
||||
{
|
||||
self.print_exception(exc);
|
||||
#[cfg(unix)]
|
||||
{
|
||||
self.print_exception(exc);
|
||||
cfg_select! {
|
||||
unix => {
|
||||
let action = SigAction::new(
|
||||
nix::sys::signal::SigHandler::SigDfl,
|
||||
SaFlags::SA_ONSTACK,
|
||||
@@ -2176,15 +2168,9 @@ impl VirtualMachine {
|
||||
|
||||
(libc::SIGINT as u32) + 128
|
||||
}
|
||||
#[cfg(windows)]
|
||||
{
|
||||
// STATUS_CONTROL_C_EXIT - same as CPython
|
||||
0xC000013A
|
||||
}
|
||||
#[cfg(not(any(unix, windows)))]
|
||||
{
|
||||
1
|
||||
}
|
||||
// STATUS_CONTROL_C_EXIT - same as CPython
|
||||
windows => 0xC000013A,
|
||||
_ => 1,
|
||||
}
|
||||
} else {
|
||||
self.print_exception(exc);
|
||||
|
||||
@@ -12,43 +12,35 @@ impl VirtualMachine {
|
||||
#[track_caller]
|
||||
#[cold]
|
||||
fn _py_panic_failed(&self, exc: PyBaseExceptionRef, msg: &str) -> ! {
|
||||
#[cfg(not(all(
|
||||
target_arch = "wasm32",
|
||||
not(any(target_os = "emscripten", target_os = "wasi")),
|
||||
)))]
|
||||
{
|
||||
self.print_exception(exc);
|
||||
self.flush_std();
|
||||
panic!("{msg}")
|
||||
}
|
||||
#[cfg(all(
|
||||
target_arch = "wasm32",
|
||||
feature = "wasmbind",
|
||||
not(any(target_os = "emscripten", target_os = "wasi")),
|
||||
))]
|
||||
#[cfg(all(target_arch = "wasm32", not(target_os = "wasi"), feature = "wasmbind"))]
|
||||
{
|
||||
use wasm_bindgen::prelude::*;
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
#[wasm_bindgen(js_namespace = console)]
|
||||
fn error(s: &str);
|
||||
cfg_select! {
|
||||
all(
|
||||
target_arch = "wasm32",
|
||||
not(any(target_os = "emscripten", target_os = "wasi"))
|
||||
) => cfg_select! {
|
||||
feature = "wasmbind" => {
|
||||
use wasm_bindgen::prelude::*;
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
#[wasm_bindgen(js_namespace = console)]
|
||||
fn error(s: &str);
|
||||
}
|
||||
let mut s = String::new();
|
||||
self.write_exception(&mut s, &exc).unwrap();
|
||||
error(&s);
|
||||
panic!("{msg}; exception backtrace above")
|
||||
}
|
||||
_ => {
|
||||
use crate::convert::ToPyObject;
|
||||
let err_string: String = exc.to_pyobject(self).repr(self).unwrap().to_string();
|
||||
eprintln!("{err_string}");
|
||||
panic!("{msg}; python exception not available")
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
self.print_exception(exc);
|
||||
self.flush_std();
|
||||
panic!("{msg}")
|
||||
}
|
||||
let mut s = String::new();
|
||||
self.write_exception(&mut s, &exc).unwrap();
|
||||
error(&s);
|
||||
panic!("{msg}; exception backtrace above")
|
||||
}
|
||||
#[cfg(all(
|
||||
target_arch = "wasm32",
|
||||
not(feature = "wasmbind"),
|
||||
not(any(target_os = "emscripten", target_os = "wasi")),
|
||||
))]
|
||||
{
|
||||
use crate::convert::ToPyObject;
|
||||
let err_string: String = exc.to_pyobject(self).repr(self).unwrap().to_string();
|
||||
eprintln!("{err_string}");
|
||||
panic!("{msg}; python exception not available")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,15 +15,14 @@ impl InterpreterBuilderExt for InterpreterBuilder {
|
||||
let defs = rustpython_stdlib::stdlib_module_defs(&self.ctx);
|
||||
let builder = self.add_native_modules(&defs);
|
||||
|
||||
#[cfg(feature = "freeze-stdlib")]
|
||||
let builder = builder
|
||||
.add_frozen_modules(rustpython_pylib::FROZEN_STDLIB)
|
||||
.init_hook(set_frozen_stdlib_dir);
|
||||
|
||||
#[cfg(not(feature = "freeze-stdlib"))]
|
||||
let builder = builder.init_hook(setup_dynamic_stdlib);
|
||||
|
||||
builder
|
||||
cfg_select! {
|
||||
feature = "freeze-stdlib" => {
|
||||
builder
|
||||
.add_frozen_modules(rustpython_pylib::FROZEN_STDLIB)
|
||||
.init_hook(set_frozen_stdlib_dir)
|
||||
}
|
||||
_ => builder.init_hook(setup_dynamic_stdlib),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,13 +63,9 @@ fn collect_stdlib_paths() -> Vec<String> {
|
||||
.map(|path| path.into_os_string().into_string().unwrap())
|
||||
.collect()
|
||||
} else {
|
||||
#[cfg(feature = "rustpython-pylib")]
|
||||
{
|
||||
vec![rustpython_pylib::LIB_PATH.to_owned()]
|
||||
}
|
||||
#[cfg(not(feature = "rustpython-pylib"))]
|
||||
{
|
||||
vec![]
|
||||
}
|
||||
vec![
|
||||
#[cfg(feature = "rustpython-pylib")]
|
||||
rustpython_pylib::LIB_PATH.to_owned(),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
22
src/lib.rs
22
src/lib.rs
@@ -176,18 +176,16 @@ fn run_file(vm: &VirtualMachine, scope: Scope, path: &str) -> PyResult<()> {
|
||||
vm.insert_sys_path(vm.new_pyobj(dir))?;
|
||||
}
|
||||
|
||||
#[cfg(feature = "host_env")]
|
||||
{
|
||||
vm.run_any_file(scope, path)
|
||||
}
|
||||
#[cfg(not(feature = "host_env"))]
|
||||
{
|
||||
// In sandbox mode, the binary reads the file and feeds source to the VM.
|
||||
// The VM itself has no filesystem access.
|
||||
let path = if path.is_empty() { "???" } else { path };
|
||||
match std::fs::read_to_string(path) {
|
||||
Ok(source) => vm.run_string(scope, &source, path.to_owned()).map(drop),
|
||||
Err(err) => Err(vm.new_os_error(err.to_string())),
|
||||
cfg_select! {
|
||||
feature = "host_env" => vm.run_any_file(scope, path),
|
||||
_ => {
|
||||
// In sandbox mode, the binary reads the file and feeds source to the VM.
|
||||
// The VM itself has no filesystem access.
|
||||
let path = if path.is_empty() { "???" } else { path };
|
||||
match std::fs::read_to_string(path) {
|
||||
Ok(source) => vm.run_string(scope, &source, path.to_owned()).map(drop),
|
||||
Err(err) => Err(vm.new_os_error(err.to_string())),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user