From a4c2b3ae304dc53e8e52cc952383b5171ce00b99 Mon Sep 17 00:00:00 2001 From: Ben Bridle Date: Wed, 15 Oct 2025 13:25:28 +1300 Subject: Raise an error if recursion depth exceeds a maximum value This is preferable to having the assembler crash with a stack overflow error, because the user can now see which invocation caused the overflow. --- src/lib.rs | 1 + src/stages/intermediate.rs | 6 ++++++ src/stages/intermediate_tokens.rs | 3 +++ 3 files changed, 10 insertions(+) (limited to 'src') diff --git a/src/lib.rs b/src/lib.rs index 9b9b87a..09e2fbb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,5 @@ const MAX_ITERATIONS_TO_STABILISE: usize = 4; +const MAX_RECURSION_DEPTH: usize = 1024; mod stages; mod types; diff --git a/src/stages/intermediate.rs b/src/stages/intermediate.rs index 07773a0..8cabe26 100644 --- a/src/stages/intermediate.rs +++ b/src/stages/intermediate.rs @@ -438,6 +438,12 @@ impl IntermediateParser { unreachable!("Uncaught duplicate macro argument name '{name}'"); }; } + // Test the current recursion depth. + if self.environment_stack.len() == MAX_RECURSION_DEPTH { + let error = IntermediateError::MaxRecursionDepthExceeded; + self.errors.push(Tracked::from(error, source.clone())); + return None; + } // Invoke the macro once. let env = Environment { arguments: argument_map, id: next_id!() }; self.environment_stack.push(env); diff --git a/src/stages/intermediate_tokens.rs b/src/stages/intermediate_tokens.rs index 2fb29fa..d796299 100644 --- a/src/stages/intermediate_tokens.rs +++ b/src/stages/intermediate_tokens.rs @@ -77,6 +77,7 @@ pub enum IntermediateError { /// expected, received ValueTooWide(u32, u32), LabelNeverStabilised(String), + MaxRecursionDepthExceeded, } pub fn report_intermediate_errors(errors: &[Tracked], source_code: &str) { @@ -116,6 +117,8 @@ fn report_intermediate_error(error: &Tracked, source_code: &s IntermediateError::LabelNeverStabilised(name) => &format!("Label '{name}' never stabilised"), + IntermediateError::MaxRecursionDepthExceeded => + &format!("Macro invocation exceededs the maximum recursion depth of {MAX_RECURSION_DEPTH}"), }; report_source_issue(LogLevel::Error, &context, message); -- cgit v1.2.3-70-g09d2