1mod manifest;
2mod stdlib;
3mod tla;
4mod trace;
5
6use std::{env, marker::PhantomData, path::PathBuf};
7
8use clap::Parser;
9use jrsonnet_evaluator::{
10 stack::{limit_stack_depth, StackDepthLimitOverrideGuard},
11 FileImportResolver,
12};
13use jrsonnet_gcmodule::{with_thread_object_space, ObjectSpace};
14pub use manifest::*;
15pub use stdlib::*;
16pub use tla::*;
17pub use trace::*;
18
19#[derive(Parser)]
20#[clap(next_help_heading = "INPUT")]
21pub struct InputOpts {
22 #[clap(long, short = 'e')]
24 pub exec: bool,
25
26 pub input: String,
28}
29
30#[derive(Parser)]
31#[clap(next_help_heading = "OPTIONS")]
32pub struct MiscOpts {
33 #[clap(long, short = 's', default_value = "512")]
36 max_stack: usize,
37
38 #[clap(long, short = 'J')]
43 jpath: Vec<PathBuf>,
44}
45impl MiscOpts {
46 pub fn import_resolver(&self) -> FileImportResolver {
47 let mut library_paths = self.jpath.clone();
48 library_paths.reverse();
49 if let Some(path) = env::var_os("JSONNET_PATH") {
50 library_paths.extend(env::split_paths(path.as_os_str()));
51 }
52
53 FileImportResolver::new(library_paths)
54 }
55 pub fn stack_size_override(&self) -> StackDepthLimitOverrideGuard {
56 limit_stack_depth(self.max_stack)
57 }
58}
59
60#[derive(Parser)]
61#[clap(next_help_heading = "GARBAGE COLLECTION")]
62pub struct GcOpts {
63 #[clap(long)]
65 gc_collect_on_exit: bool,
66 #[clap(long)]
68 gc_print_stats: bool,
69 #[clap(long)]
73 gc_collect_before_printing_stats: bool,
74}
75impl GcOpts {
76 pub fn stats_printer(&self) -> Option<GcStatsPrinter> {
77 #[allow(clippy::unnecessary_lazy_evaluations)]
78 self.gc_print_stats.then(|| GcStatsPrinter {
79 collect_before_printing_stats: self.gc_collect_before_printing_stats,
80 })
81 }
82 pub fn leak_on_exit(&self) -> Option<LeakSpace> {
83 (!self.gc_collect_on_exit).then(|| LeakSpace(PhantomData))
84 }
85}
86
87pub struct LeakSpace(PhantomData<()>);
88
89impl Drop for LeakSpace {
90 fn drop(&mut self) {
91 with_thread_object_space(ObjectSpace::leak);
92 }
93}
94
95pub struct GcStatsPrinter {
96 collect_before_printing_stats: bool,
97}
98impl Drop for GcStatsPrinter {
99 fn drop(&mut self) {
100 eprintln!("=== GC STATS ===");
101 if self.collect_before_printing_stats {
102 let collected = jrsonnet_gcmodule::collect_thread_cycles();
103 eprintln!("Collected: {collected}");
104 }
105 eprintln!("Tracked: {}", jrsonnet_gcmodule::count_thread_tracked());
106 }
107}