return an error when the parser is at its event capacity

This commit is contained in:
liquidex 2024-09-02 20:40:59 +02:00
parent 26d3b8ed8a
commit 337de0b57b
2 changed files with 16 additions and 1 deletions

View file

@ -220,6 +220,7 @@ enum StatusCode {
SourceCodeTooLong, SourceCodeTooLong,
TooManyTokens, TooManyTokens,
TooManyAstNodes, TooManyAstNodes,
TooManyParserEvents,
ParserUnbalancedEvents, ParserUnbalancedEvents,
ChunkTooBig, ChunkTooBig,
DiagnosticsEmitted, DiagnosticsEmitted,
@ -254,6 +255,7 @@ extern "C" fn haku_status_string(code: StatusCode) -> *const i8 {
StatusCode::SourceCodeTooLong => c"source code is too long", StatusCode::SourceCodeTooLong => c"source code is too long",
StatusCode::TooManyTokens => c"source code has too many tokens", StatusCode::TooManyTokens => c"source code has too many tokens",
StatusCode::TooManyAstNodes => c"source code has too many AST nodes", StatusCode::TooManyAstNodes => c"source code has too many AST nodes",
StatusCode::TooManyParserEvents => c"source code has too many parser events",
StatusCode::ParserUnbalancedEvents => c"parser produced unbalanced events", StatusCode::ParserUnbalancedEvents => c"parser produced unbalanced events",
StatusCode::ChunkTooBig => c"compiled bytecode is too large", StatusCode::ChunkTooBig => c"compiled bytecode is too large",
StatusCode::DiagnosticsEmitted => c"diagnostics were emitted", StatusCode::DiagnosticsEmitted => c"diagnostics were emitted",
@ -365,6 +367,10 @@ unsafe extern "C" fn haku_compile_brush(
info!("compiling failed: too many AST nodes"); info!("compiling failed: too many AST nodes");
return StatusCode::TooManyAstNodes; return StatusCode::TooManyAstNodes;
} }
Err(IntoAstError::TooManyEvents) => {
info!("compiling failed: too many parser events");
return StatusCode::TooManyParserEvents;
}
Err(IntoAstError::UnbalancedEvents) => { Err(IntoAstError::UnbalancedEvents) => {
info!("compiling failed: parser produced unbalanced events"); info!("compiling failed: parser produced unbalanced events");
return StatusCode::ParserUnbalancedEvents; return StatusCode::ParserUnbalancedEvents;

View file

@ -52,7 +52,9 @@ impl<'a> Parser<'a> {
Self { Self {
tokens: input, tokens: input,
events: Vec::with_capacity(limits.max_events), // Add one event to the capacity, because that makes it easier to detect when we ran out
// of space. (No need to store flags or anything, just check if events are at capacity.)
events: Vec::with_capacity(limits.max_events + 1),
position: 0, position: 0,
diagnostics: Vec::with_capacity(16), diagnostics: Vec::with_capacity(16),
fuel: Cell::new(Self::FUEL), fuel: Cell::new(Self::FUEL),
@ -153,6 +155,11 @@ impl<'a> Parser<'a> {
} }
pub fn into_ast(self, ast: &mut Ast) -> Result<(NodeId, Vec<Diagnostic>), IntoAstError> { pub fn into_ast(self, ast: &mut Ast) -> Result<(NodeId, Vec<Diagnostic>), IntoAstError> {
// If events are at capacity, that means the pool was exhausted and we return an error.
if self.events.len() == self.events.capacity() {
return Err(IntoAstError::TooManyEvents);
}
let mut token = 0; let mut token = 0;
let mut events = self.events; let mut events = self.events;
let mut stack = Vec::new(); let mut stack = Vec::new();
@ -260,6 +267,7 @@ impl fmt::Debug for Event {
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum IntoAstError { pub enum IntoAstError {
NodeAlloc(NodeAllocError), NodeAlloc(NodeAllocError),
TooManyEvents,
UnbalancedEvents, UnbalancedEvents,
} }
@ -273,6 +281,7 @@ impl fmt::Display for IntoAstError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self { match self {
IntoAstError::NodeAlloc(e) => fmt::Display::fmt(e, f), IntoAstError::NodeAlloc(e) => fmt::Display::fmt(e, f),
IntoAstError::TooManyEvents => f.write_str("too many parser events"),
IntoAstError::UnbalancedEvents => f.write_str("parser produced unbalanced events"), IntoAstError::UnbalancedEvents => f.write_str("parser produced unbalanced events"),
} }
} }