summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib.rs1
-rw-r--r--src/stages/intermediate.rs6
-rw-r--r--src/stages/intermediate_tokens.rs3
3 files changed, 10 insertions, 0 deletions
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<IntermediateError>], source_code: &str) {
@@ -116,6 +117,8 @@ fn report_intermediate_error(error: &Tracked<IntermediateError>, 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);