1use crate::error::{bail, Error};
2
3#[derive(Copy, Clone, PartialEq, Eq, Debug)]
4pub enum BackendKind {
5 Compiler,
6 Interpreter,
7}
8
9impl core::fmt::Display for BackendKind {
10 fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
11 let name = match self {
12 BackendKind::Compiler => "compiler",
13 BackendKind::Interpreter => "interpreter",
14 };
15
16 fmt.write_str(name)
17 }
18}
19
20impl BackendKind {
21 fn from_os_str(s: &std::ffi::OsStr) -> Result<Option<BackendKind>, Error> {
22 if s == "auto" {
23 Ok(None)
24 } else if s == "interpreter" {
25 Ok(Some(BackendKind::Interpreter))
26 } else if s == "compiler" {
27 Ok(Some(BackendKind::Compiler))
28 } else {
29 Err(Error::from_static_str(
30 "invalid value of POLKAVM_BACKEND; supported values are: 'interpreter', 'compiler'",
31 ))
32 }
33 }
34}
35
36impl BackendKind {
37 pub fn is_supported(self) -> bool {
38 match self {
39 BackendKind::Interpreter => true,
40 BackendKind::Compiler => if_compiler_is_supported! {
41 { true } else { false }
42 },
43 }
44 }
45}
46
47#[derive(Copy, Clone, PartialEq, Eq, Debug)]
48pub enum SandboxKind {
49 Linux,
50 Generic,
51}
52
53impl core::fmt::Display for SandboxKind {
54 fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
55 let name = match self {
56 SandboxKind::Linux => "linux",
57 SandboxKind::Generic => "generic",
58 };
59
60 fmt.write_str(name)
61 }
62}
63
64impl SandboxKind {
65 fn from_os_str(s: &std::ffi::OsStr) -> Result<Option<SandboxKind>, Error> {
66 if s == "auto" {
67 Ok(None)
68 } else if s == "linux" {
69 Ok(Some(SandboxKind::Linux))
70 } else if s == "generic" {
71 Ok(Some(SandboxKind::Generic))
72 } else {
73 Err(Error::from_static_str(
74 "invalid value of POLKAVM_SANDBOX; supported values are: 'linux', 'generic'",
75 ))
76 }
77 }
78}
79
80impl SandboxKind {
81 pub fn is_supported(self) -> bool {
82 if_compiler_is_supported! {
83 {
84 match self {
85 SandboxKind::Linux => cfg!(target_os = "linux"),
86 SandboxKind::Generic => true
87 }
88 } else {
89 false
90 }
91 }
92 }
93}
94
95#[derive(Clone)]
96pub struct Config {
97 pub(crate) backend: Option<BackendKind>,
98 pub(crate) sandbox: Option<SandboxKind>,
99 pub(crate) trace_execution: bool,
100 pub(crate) allow_insecure: bool,
101 pub(crate) worker_count: usize,
102}
103
104impl Default for Config {
105 fn default() -> Self {
106 Self::new()
107 }
108}
109
110fn env_bool(name: &str) -> Result<Option<bool>, Error> {
111 if let Some(value) = std::env::var_os(name) {
112 if value == "1" || value == "true" {
113 Ok(Some(true))
114 } else if value == "0" || value == "false" {
115 Ok(Some(false))
116 } else {
117 bail!("invalid value of {name}; must be either '1' or '0'")
118 }
119 } else {
120 Ok(None)
121 }
122}
123
124impl Config {
125 pub fn new() -> Self {
127 Config {
128 backend: None,
129 sandbox: None,
130 trace_execution: false,
131 allow_insecure: false,
132 worker_count: 2,
133 }
134 }
135
136 pub fn from_env() -> Result<Self, Error> {
138 let mut config = Self::new();
139 if let Some(value) = std::env::var_os("POLKAVM_BACKEND") {
140 config.backend = BackendKind::from_os_str(&value)?;
141 }
142
143 if let Some(value) = std::env::var_os("POLKAVM_SANDBOX") {
144 config.sandbox = SandboxKind::from_os_str(&value)?;
145 }
146
147 if let Some(value) = env_bool("POLKAVM_TRACE_EXECUTION")? {
148 config.trace_execution = value;
149 }
150
151 if let Some(value) = env_bool("POLKAVM_ALLOW_INSECURE")? {
152 config.allow_insecure = value;
153 }
154
155 Ok(config)
156 }
157
158 pub fn set_backend(&mut self, backend: Option<BackendKind>) -> &mut Self {
164 self.backend = backend;
165 self
166 }
167
168 pub fn backend(&self) -> Option<BackendKind> {
170 self.backend
171 }
172
173 pub fn set_sandbox(&mut self, sandbox: Option<SandboxKind>) -> &mut Self {
179 self.sandbox = sandbox;
180 self
181 }
182
183 pub fn sandbox(&self) -> Option<SandboxKind> {
185 self.sandbox
186 }
187
188 pub fn set_trace_execution(&mut self, value: bool) -> &mut Self {
196 self.trace_execution = value;
197 self
198 }
199
200 pub fn trace_execution(&self) -> bool {
202 self.trace_execution
203 }
204
205 pub fn set_allow_insecure(&mut self, value: bool) -> &mut Self {
214 self.allow_insecure = value;
215 self
216 }
217
218 pub fn set_worker_count(&mut self, value: usize) -> &mut Self {
229 self.worker_count = value;
230 self
231 }
232}
233
234#[derive(Copy, Clone, PartialEq, Eq, Debug)]
236pub enum GasMeteringKind {
237 Sync,
239 Async,
250}
251
252#[derive(Clone)]
254pub struct ModuleConfig {
255 pub(crate) page_size: u32,
256 pub(crate) gas_metering: Option<GasMeteringKind>,
257}
258
259impl Default for ModuleConfig {
260 fn default() -> Self {
261 Self::new()
262 }
263}
264
265impl ModuleConfig {
266 pub fn new() -> Self {
268 ModuleConfig {
269 page_size: 0x4000,
270 gas_metering: None,
271 }
272 }
273
274 pub fn set_page_size(&mut self, page_size: u32) -> &mut Self {
278 self.page_size = page_size;
279 self
280 }
281
282 pub fn set_gas_metering(&mut self, kind: Option<GasMeteringKind>) -> &mut Self {
286 self.gas_metering = kind;
287 self
288 }
289}