diff --git a/compiler/erg_common/lib.rs b/compiler/erg_common/lib.rs index 3d1fde36..3547c47a 100644 --- a/compiler/erg_common/lib.rs +++ b/compiler/erg_common/lib.rs @@ -21,6 +21,7 @@ pub mod python_util; pub mod serialize; pub mod set; pub mod shared; +pub mod spawn; pub mod stdin; pub mod str; pub mod style; diff --git a/compiler/erg_common/spawn.rs b/compiler/erg_common/spawn.rs new file mode 100644 index 00000000..60cf8857 --- /dev/null +++ b/compiler/erg_common/spawn.rs @@ -0,0 +1,22 @@ +use std::thread; + +/// Execute a function in a new thread on Windows, otherwise just run it. +/// +/// Windows has a smaller default stack size than other OSs, which may cause a stack overflow, especially in the parsing process. +pub fn exec_new_thread(run: F) -> T +where + F: FnOnce() -> T + Send + 'static, + T: Send + 'static, +{ + if cfg!(windows) { + const STACK_SIZE: usize = 4 * 1024 * 1024; + let child = thread::Builder::new() + .stack_size(STACK_SIZE) + .spawn(run) + .unwrap(); + // Wait for thread to join + child.join().unwrap() + } else { + run() + } +} diff --git a/compiler/erg_compiler/main.rs b/compiler/erg_compiler/main.rs index cfb8190f..2e23795b 100644 --- a/compiler/erg_compiler/main.rs +++ b/compiler/erg_compiler/main.rs @@ -3,9 +3,9 @@ extern crate erg_compiler; extern crate erg_parser; use std::process; -use std::thread; use erg_common::config::ErgConfig; +use erg_common::spawn::exec_new_thread; use erg_common::traits::Runnable; use erg_compiler::build_hir::HIRBuilder; @@ -49,17 +49,5 @@ fn run() { } fn main() { - if cfg!(windows) { - const STACK_SIZE: usize = 4 * 1024 * 1024; - - let child = thread::Builder::new() - .stack_size(STACK_SIZE) - .spawn(run) - .unwrap(); - - // Wait for thread to join - child.join().unwrap(); - } else { - run(); - } + exec_new_thread(run); } diff --git a/compiler/erg_parser/main.rs b/compiler/erg_parser/main.rs index 659a69b4..7a701d6a 100644 --- a/compiler/erg_parser/main.rs +++ b/compiler/erg_parser/main.rs @@ -2,9 +2,9 @@ extern crate erg_common; extern crate erg_parser; use std::process; -use std::thread; use erg_common::config::ErgConfig; +use erg_common::spawn::exec_new_thread; use erg_common::traits::Runnable; use erg_parser::build_ast::ASTBuilder; @@ -31,17 +31,5 @@ fn run() { } fn main() { - if cfg!(windows) { - const STACK_SIZE: usize = 4 * 1024 * 1024; - - let child = thread::Builder::new() - .stack_size(STACK_SIZE) - .spawn(run) - .unwrap(); - - // Wait for thread to join - child.join().unwrap(); - } else { - run(); - } + exec_new_thread(run); } diff --git a/src/main.rs b/src/main.rs index 446183b2..72ecc2c0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,10 +3,9 @@ extern crate erg_compiler; extern crate erg_parser; use std::process; -#[cfg(target_os = "windows")] -use std::thread; use erg_common::config::ErgConfig; +use erg_common::spawn::exec_new_thread; use erg_common::traits::Runnable; use erg_parser::build_ast::ASTBuilder; @@ -59,18 +58,5 @@ fn run() { } fn main() { - #[cfg(target_os = "windows")] - { - const STACK_SIZE: usize = 4 * 1024 * 1024; - - let child = thread::Builder::new() - .stack_size(STACK_SIZE) - .spawn(run) - .unwrap(); - - // Wait for thread to join - child.join().unwrap(); - } - #[cfg(not(target_os = "windows"))] - run(); + exec_new_thread(run); } diff --git a/tests/test.rs b/tests/test.rs index fddb5b72..459226dc 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -3,6 +3,7 @@ use std::path::PathBuf; use erg_common::config::ErgConfig; use erg_common::error::MultiErrorDisplay; use erg_common::python_util::PythonVersion; +use erg_common::spawn::exec_new_thread; use erg_common::traits::{Runnable, Stream}; use erg_compiler::error::CompileErrors; @@ -268,19 +269,6 @@ fn _exec_vm(file_path: &'static str) -> Result { vm.exec() } -#[cfg(target_os = "windows")] fn exec_vm(file_path: &'static str) -> Result { - const STACK_SIZE: usize = 4 * 1024 * 1024; - - let child = std::thread::Builder::new() - .stack_size(STACK_SIZE) - .spawn(move || _exec_vm(file_path)) - .unwrap(); - // Wait for thread to join - child.join().unwrap() -} - -#[cfg(not(target_os = "windows"))] -fn exec_vm(file_path: &'static str) -> Result { - _exec_vm(file_path) + exec_new_thread(move || _exec_vm(file_path)) }