diff --git a/crates/oxide_kernel/src/kernel.rs b/crates/oxide_kernel/src/kernel.rs index 6c9ba573..fcfa02e7 100644 --- a/crates/oxide_kernel/src/kernel.rs +++ b/crates/oxide_kernel/src/kernel.rs @@ -16,6 +16,7 @@ pub struct KernelConfig { pub min_pool_size: usize, pub max_pool_size: Option, pub max_dead_strings: Option, + pub max_call_depth: usize, pub warmup_builtin_shapes: bool, pub warmup_builtin_code: bool, pub warmup_builtin_ic: bool, @@ -27,6 +28,7 @@ impl KernelConfig { min_pool_size: 4, max_pool_size: Some(8), max_dead_strings: Some(10_000), + max_call_depth: 1024, warmup_builtin_shapes: true, warmup_builtin_code: false, warmup_builtin_ic: false, @@ -38,6 +40,7 @@ impl KernelConfig { min_pool_size: 8, max_pool_size: Some(32), max_dead_strings: Some(10_000), + max_call_depth: 1024, warmup_builtin_shapes: true, warmup_builtin_code: true, warmup_builtin_ic: false, @@ -49,6 +52,7 @@ impl KernelConfig { min_pool_size: 16, max_pool_size: None, max_dead_strings: Some(5_000), + max_call_depth: 1024, warmup_builtin_shapes: true, warmup_builtin_code: true, warmup_builtin_ic: true, diff --git a/crates/oxide_vm/src/vm.rs b/crates/oxide_vm/src/vm.rs index 78fc4718..2759b543 100644 --- a/crates/oxide_vm/src/vm.rs +++ b/crates/oxide_vm/src/vm.rs @@ -1145,6 +1145,12 @@ impl Vm { )); } + if self.frames.len() >= self.kernel.config.max_call_depth { + return Err( + "RangeError: Maximum call stack size exceeded".into() + ); + } + // Clone sub_module data before mutably borrowing self let sub_bytecode = self.sub_modules[sub_idx].bytecode.clone(); let sub_n_args = self.sub_modules[sub_idx].n_args as usize;