Skip to main content

neo_devpack_solidity/cli/cli_parts/cli_run/
run.rs

1/// Stack budget for the compiler driver thread spawned by [`run`]. Keep in
2/// sync with `PARSE_THREAD_STACK_BYTES` in
3/// src/frontend/frontend_guarded_parse.rs so every stage shares one ceiling.
4const DRIVER_THREAD_STACK_BYTES: usize = 256 * 1024 * 1024;
5
6pub fn run() {
7    // The Solidity AST is deeply recursive. Parsing is guarded by
8    // `frontend::parse_solidity_guarded` (own worker thread, large stack)
9    // and the IR lowering walks are `stacker`-guarded, but other passes
10    // still recurse over the full tree on the calling thread's stack —
11    // e.g. the derive(Clone) walk in `analyse_all_sources` and the
12    // recursive `Drop` of the parse tree at scope exit. Run the whole
13    // driver on a worker thread with a large bounded stack so a deeply
14    // nested (but otherwise valid) source can't abort the process with a
15    // main-thread stack overflow.
16    let worker = std::thread::Builder::new()
17        .name("neo-solc-driver".to_string())
18        .stack_size(DRIVER_THREAD_STACK_BYTES)
19        .spawn(run_driver);
20
21    match worker {
22        Ok(handle) => {
23            if let Err(panic) = handle.join() {
24                std::panic::resume_unwind(panic);
25            }
26        }
27        // Spawning a thread only fails under extreme resource exhaustion;
28        // fall back to running on the current thread (pre-guard behavior)
29        // rather than refusing to compile.
30        Err(_) => run_driver(),
31    }
32}
33
34fn run_driver() {
35    let matches = build_matches();
36
37    if try_run_standard_json(&matches) {
38        return;
39    }
40
41    run_single_file(&matches);
42}