chore: eliminate thread_local!

This commit is contained in:
Shunsuke Shibayama 2023-06-10 16:07:50 +09:00
parent d6f30924f1
commit 393a018fb9
5 changed files with 63 additions and 84 deletions

View file

@ -1,6 +1,5 @@
use std::cell::RefCell;
use std::io; use std::io;
use std::io::{stdin, stdout, BufRead, Read, StdinLock, StdoutLock, Write}; use std::io::{stdin, stdout, BufRead, Read, Write};
use std::ops::Not; use std::ops::Not;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::str::FromStr; use std::str::FromStr;
@ -123,39 +122,24 @@ macro_rules! _log {
}; };
} }
thread_local! {
static INPUT: RefCell<StdinLock<'static>> = RefCell::new(stdin().lock());
static OUTPUT: RefCell<StdoutLock<'static>> = RefCell::new(stdout().lock());
}
fn send_stdout<T: ?Sized + Serialize>(message: &T) -> ELSResult<()> { fn send_stdout<T: ?Sized + Serialize>(message: &T) -> ELSResult<()> {
let msg = serde_json::to_string(message)?; let msg = serde_json::to_string(message)?;
OUTPUT.with(|out| { let mut stdout = stdout().lock();
write!( write!(stdout, "Content-Length: {}\r\n\r\n{}", msg.len(), msg)?;
out.borrow_mut(), stdout.flush()?;
"Content-Length: {}\r\n\r\n{}", Ok(())
msg.len(),
msg
)?;
out.borrow_mut().flush()?;
Ok(())
})
} }
fn read_line() -> io::Result<String> { fn read_line() -> io::Result<String> {
let mut line = String::new(); let mut line = String::new();
INPUT.with(|input| { stdin().lock().read_line(&mut line)?;
input.borrow_mut().read_line(&mut line)?; Ok(line)
Ok(line)
})
} }
fn read_exact(len: usize) -> io::Result<Vec<u8>> { fn read_exact(len: usize) -> io::Result<Vec<u8>> {
let mut buf = vec![0; len]; let mut buf = vec![0; len];
INPUT.with(|input| { stdin().lock().read_exact(&mut buf)?;
input.borrow_mut().read_exact(&mut buf)?; Ok(buf)
Ok(buf)
})
} }
pub(crate) fn send<T: ?Sized + Serialize>(message: &T) -> ELSResult<()> { pub(crate) fn send<T: ?Sized + Serialize>(message: &T) -> ELSResult<()> {
@ -228,7 +212,7 @@ impl<Checker: BuildRunnable, Parser: Parsable> Server<Checker, Parser> {
comp_cache: CompletionCache::new(cfg.copy()), comp_cache: CompletionCache::new(cfg.copy()),
cfg, cfg,
home: normalize_path(std::env::current_dir().unwrap_or_default()), home: normalize_path(std::env::current_dir().unwrap_or_default()),
erg_path: erg_path(), // already normalized erg_path: erg_path().clone(), // already normalized
client_capas: ClientCapabilities::default(), client_capas: ClientCapabilities::default(),
disabled_features: vec![], disabled_features: vec![],
opt_features: vec![], opt_features: vec![],

View file

@ -1,5 +1,6 @@
use std::env::var; use std::env::var;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::sync::OnceLock;
use crate::normalize_path; use crate::normalize_path;
use crate::python_util::get_sys_path; use crate::python_util::get_sys_path;
@ -66,37 +67,35 @@ fn _python_site_packages() -> impl Iterator<Item = PathBuf> {
}) })
} }
thread_local! { pub static ERG_PATH: OnceLock<PathBuf> = OnceLock::new();
pub static ERG_PATH: PathBuf = normalize_path(_erg_path()); pub static ERG_STD_PATH: OnceLock<PathBuf> = OnceLock::new();
pub static ERG_STD_PATH: PathBuf = normalize_path(_erg_std_path()); pub static ERG_STD_DECL_PATH: OnceLock<PathBuf> = OnceLock::new();
pub static ERG_STD_DECL_PATH: PathBuf = normalize_path(_erg_std_decl_path()); pub static ERG_PYSTD_PATH: OnceLock<PathBuf> = OnceLock::new();
pub static ERG_PYSTD_PATH: PathBuf = normalize_path(_erg_pystd_path()); pub static ERG_EXTERNAL_LIB_PATH: OnceLock<PathBuf> = OnceLock::new();
pub static ERG_EXTERNAL_LIB_PATH: PathBuf = normalize_path(_erg_external_lib_path()); pub static PYTHON_SITE_PACKAGES: OnceLock<Vec<PathBuf>> = OnceLock::new();
pub static PYTHON_SITE_PACKAGES: Vec<PathBuf> = _python_site_packages().collect();
pub fn erg_path() -> &'static PathBuf {
ERG_PATH.get_or_init(|| normalize_path(_erg_path())) // .with(|s| s.clone())
} }
pub fn erg_path() -> PathBuf { pub fn erg_std_path() -> &'static PathBuf {
ERG_PATH.with(|s| s.clone()) ERG_STD_PATH.get_or_init(|| normalize_path(_erg_std_path()))
} }
pub fn erg_std_path() -> PathBuf { pub fn erg_std_decl_path() -> &'static PathBuf {
ERG_STD_PATH.with(|s| s.clone()) ERG_STD_DECL_PATH.get_or_init(|| normalize_path(_erg_std_decl_path()))
} }
pub fn erg_std_decl_path() -> PathBuf { pub fn erg_pystd_path() -> &'static PathBuf {
ERG_STD_DECL_PATH.with(|s| s.clone()) ERG_PYSTD_PATH.get_or_init(|| normalize_path(_erg_pystd_path()))
} }
pub fn erg_pystd_path() -> PathBuf { pub fn erg_py_external_lib_path() -> &'static PathBuf {
ERG_PYSTD_PATH.with(|s| s.clone()) ERG_EXTERNAL_LIB_PATH.get_or_init(|| normalize_path(_erg_external_lib_path()))
} }
pub fn erg_py_external_lib_path() -> PathBuf { pub fn python_site_packages() -> &'static Vec<PathBuf> {
ERG_EXTERNAL_LIB_PATH.with(|s| s.clone()) PYTHON_SITE_PACKAGES.get_or_init(|| _python_site_packages().collect())
}
pub fn python_site_packages() -> Vec<PathBuf> {
PYTHON_SITE_PACKAGES.with(|s| s.clone())
} }
pub fn is_std_decl_path(path: &Path) -> bool { pub fn is_std_decl_path(path: &Path) -> bool {
@ -113,6 +112,5 @@ pub fn is_pystd_main_module(path: &Path) -> bool {
} else { } else {
path.pop(); path.pop();
} }
let pystd_path = erg_pystd_path(); path == erg_pystd_path().as_path()
path == pystd_path
} }

View file

@ -604,7 +604,7 @@ impl Input {
/// 1. `site-packages/{path/to}.d.er` /// 1. `site-packages/{path/to}.d.er`
/// 2. `site-packages/{path.d/to.d}/__init__.d.er` /// 2. `site-packages/{path.d/to.d}/__init__.d.er`
fn resolve_std_decl_path(root: PathBuf, path: &Path) -> Option<PathBuf> { fn resolve_std_decl_path(root: &Path, path: &Path) -> Option<PathBuf> {
let mut path = add_postfix_foreach(path, ".d"); let mut path = add_postfix_foreach(path, ".d");
path.set_extension("d.er"); // set_extension overrides the previous one path.set_extension("d.er"); // set_extension overrides the previous one
if let Ok(path) = root.join(&path).canonicalize() { if let Ok(path) = root.join(&path).canonicalize() {
@ -629,7 +629,7 @@ impl Input {
/// ///
/// e.g. `toml/encoder` /// e.g. `toml/encoder`
/// -> `site-packages/toml/__pycache__/encoder.d.er`, `site-packages/toml/encoder/__pycache__/__init__.d.er` /// -> `site-packages/toml/__pycache__/encoder.d.er`, `site-packages/toml/encoder/__pycache__/__init__.d.er`
fn resolve_site_pkgs_decl_path(site_packages: PathBuf, path: &Path) -> Option<PathBuf> { fn resolve_site_pkgs_decl_path(site_packages: &Path, path: &Path) -> Option<PathBuf> {
let dir = path.parent().unwrap_or_else(|| Path::new("")); let dir = path.parent().unwrap_or_else(|| Path::new(""));
let mut file_path = PathBuf::from(path.file_stem().unwrap_or_default()); let mut file_path = PathBuf::from(path.file_stem().unwrap_or_default());
file_path.set_extension("d.er"); // set_extension overrides the previous one file_path.set_extension("d.er"); // set_extension overrides the previous one

View file

@ -1,5 +1,4 @@
use std::cell::RefCell; use std::sync::OnceLock;
use std::thread::LocalKey;
#[cfg(not(feature = "full-repl"))] #[cfg(not(feature = "full-repl"))]
use std::io::{stdin, BufRead, BufReader}; use std::io::{stdin, BufRead, BufReader};
@ -18,6 +17,8 @@ use std::process::Command;
#[cfg(feature = "full-repl")] #[cfg(feature = "full-repl")]
use std::process::Output; use std::process::Output;
use crate::shared::AtomicShared;
/// e.g. /// e.g.
/// ```erg /// ```erg
/// >>> print! 1 /// >>> print! 1
@ -261,57 +262,56 @@ impl StdinReader {
} }
} }
thread_local! {
static READER: RefCell<StdinReader> = RefCell::new(StdinReader{
block_begin: 1,
lineno: 1,
buf: vec![],
#[cfg(feature = "full-repl")]
history_input_position: 1,
indent: 1
});
}
#[derive(Debug)] #[derive(Debug)]
pub struct GlobalStdin(LocalKey<RefCell<StdinReader>>); pub struct GlobalStdin(OnceLock<AtomicShared<StdinReader>>);
pub static GLOBAL_STDIN: GlobalStdin = GlobalStdin(READER); pub static GLOBAL_STDIN: GlobalStdin = GlobalStdin(OnceLock::new());
impl GlobalStdin { impl GlobalStdin {
fn get(&'static self) -> &'static AtomicShared<StdinReader> {
self.0.get_or_init(|| {
AtomicShared::new(StdinReader {
block_begin: 1,
lineno: 1,
buf: vec![],
#[cfg(feature = "full-repl")]
history_input_position: 1,
indent: 1,
})
})
}
pub fn read(&'static self) -> String { pub fn read(&'static self) -> String {
self.0.with(|s| s.borrow_mut().read()) self.get().borrow_mut().read()
} }
pub fn reread(&'static self) -> String { pub fn reread(&'static self) -> String {
self.0.with(|s| s.borrow().reread()) self.get().borrow_mut().reread()
} }
pub fn reread_lines(&'static self, ln_begin: usize, ln_end: usize) -> Vec<String> { pub fn reread_lines(&'static self, ln_begin: usize, ln_end: usize) -> Vec<String> {
self.0 self.get().borrow_mut().reread_lines(ln_begin, ln_end)
.with(|s| s.borrow_mut().reread_lines(ln_begin, ln_end))
} }
pub fn lineno(&'static self) -> usize { pub fn lineno(&'static self) -> usize {
self.0.with(|s| s.borrow().lineno) self.get().borrow_mut().lineno
} }
pub fn block_begin(&'static self) -> usize { pub fn block_begin(&'static self) -> usize {
self.0.with(|s| s.borrow().block_begin) self.get().borrow_mut().block_begin
} }
pub fn set_block_begin(&'static self, n: usize) { pub fn set_block_begin(&'static self, n: usize) {
self.0.with(|s| s.borrow_mut().block_begin = n); self.get().borrow_mut().block_begin = n;
} }
pub fn set_indent(&'static self, n: usize) { pub fn set_indent(&'static self, n: usize) {
self.0.with(|s| s.borrow_mut().indent = n as u16); self.get().borrow_mut().indent = n as u16;
} }
pub fn insert_whitespace(&'static self, whitespace: &str) { pub fn insert_whitespace(&'static self, whitespace: &str) {
self.0.with(|s| { if let Some(line) = self.get().borrow_mut().last_line() {
if let Some(line) = s.borrow_mut().last_line() { line.insert_str(0, whitespace);
line.insert_str(0, whitespace); }
}
})
} }
} }

View file

@ -15,6 +15,7 @@ use std::path::PathBuf;
use erg_common::config::ErgConfig; use erg_common::config::ErgConfig;
use erg_common::consts::{DEBUG_MODE, ERG_MODE, PYTHON_MODE}; use erg_common::consts::{DEBUG_MODE, ERG_MODE, PYTHON_MODE};
use erg_common::dict; use erg_common::dict;
use erg_common::env::erg_std_decl_path;
use erg_common::error::Location; use erg_common::error::Location;
#[allow(unused_imports)] #[allow(unused_imports)]
use erg_common::log; use erg_common::log;
@ -515,10 +516,6 @@ pub fn builtins_path() -> PathBuf {
erg_common::env::erg_pystd_path().join("builtins.d.er") erg_common::env::erg_pystd_path().join("builtins.d.er")
} }
pub fn std_decl_path() -> PathBuf {
erg_common::env::erg_std_decl_path()
}
impl Context { impl Context {
fn register_builtin_decl( fn register_builtin_decl(
&mut self, &mut self,
@ -667,7 +664,7 @@ impl Context {
let module = if &self.name[..] == "<builtins>" { let module = if &self.name[..] == "<builtins>" {
builtins_path() builtins_path()
} else { } else {
std_decl_path().join(format!("{}.d.er", self.name)) erg_std_decl_path().join(format!("{}.d.er", self.name))
}; };
let abs_loc = AbsLocation::new(Some(module), loc); let abs_loc = AbsLocation::new(Some(module), loc);
self.register_builtin_impl(name, t, muty, vis, py_name, abs_loc); self.register_builtin_impl(name, t, muty, vis, py_name, abs_loc);