glsl-in: Improve the context emitter interface

Adds a new method `emit_restart` to perform the common operation of flushing
the `emitter` to the body and starting it again.

Adds documentation to all context emitter related methods
This commit is contained in:
João Capucho
2022-04-30 14:50:11 +01:00
committed by Jim Blandy
parent 1c02de537b
commit 6a62d009ea
5 changed files with 53 additions and 41 deletions

View File

@@ -1837,7 +1837,7 @@ impl MacroCall {
MacroCall::ImageStore => {
let comps =
parser.coordinate_components(ctx, args[0], args[1], None, meta, body)?;
ctx.emit_flush(body);
ctx.emit_restart(body);
body.push(
crate::Statement::ImageStore {
image: args[0],
@@ -1847,7 +1847,6 @@ impl MacroCall {
},
meta,
);
ctx.emit_start();
return Ok(None);
}
MacroCall::MathFunction(fun) => ctx.add_expression(
@@ -2038,8 +2037,7 @@ impl MacroCall {
body,
),
MacroCall::Barrier => {
ctx.emit_flush(body);
ctx.emit_start();
ctx.emit_restart(body);
body.push(crate::Statement::Barrier(crate::Barrier::all()), meta);
return Ok(None);
}

View File

@@ -101,7 +101,7 @@ impl Context {
}: GlobalLookup,
body: &mut Block,
) {
self.emit_flush(body);
self.emit_end(body);
let (expr, load, constant) = match kind {
GlobalLookupKind::Variable(v) => {
let span = parser.module.global_variables.get_span(v);
@@ -170,14 +170,37 @@ impl Context {
self.lookup_global_var_exps.insert(name.into(), var);
}
/// Starts the expression emitter
///
/// # Panics
///
/// - If called twice in a row without calling [`emit_end`][Self::emit_end].
#[inline]
pub fn emit_start(&mut self) {
self.emitter.start(&self.expressions)
}
pub fn emit_flush(&mut self, body: &mut Block) {
/// Emits all the expressions captured by the emitter to the passed `body`
///
/// # Panics
///
/// - If called before calling [`emit_start`][Self::emit_start].
/// - If called twice in a row without calling [`emit_start`][Self::emit_start].
pub fn emit_end(&mut self, body: &mut Block) {
body.extend(self.emitter.finish(&self.expressions))
}
/// Emits all the expressions captured by the emitter to the passed `body`
/// and starts the emitter again
///
/// # Panics
///
/// - If called before calling [`emit_start`][Self::emit_start].
pub fn emit_restart(&mut self, body: &mut Block) {
self.emit_end(body);
self.emit_start()
}
pub fn add_expression(
&mut self,
expr: Expression,
@@ -186,7 +209,7 @@ impl Context {
) -> Handle<Expression> {
let needs_pre_emit = expr.needs_pre_emit();
if needs_pre_emit {
self.emit_flush(body);
self.emit_end(body);
}
let handle = self.expressions.append(expr, meta);
if needs_pre_emit {
@@ -292,8 +315,7 @@ impl Context {
);
let local_expr = self.add_expression(Expression::LocalVariable(handle), meta, body);
self.emit_flush(body);
self.emit_start();
self.emit_restart(body);
body.push(
Statement::Store {
@@ -462,8 +484,7 @@ impl Context {
body,
);
self.emit_flush(body);
self.emit_start();
self.emit_restart(body);
body.push(
Statement::Store {
@@ -474,8 +495,7 @@ impl Context {
);
}
} else {
self.emit_flush(body);
self.emit_start();
self.emit_restart(body);
body.push(Statement::Store { pointer, value }, meta);
}
@@ -1086,8 +1106,7 @@ impl Context {
// Emit all expressions since we will be adding statements to
// other bodies next
self.emit_flush(body);
self.emit_start();
self.emit_restart(body);
// Create the bodies for the two cases
let mut accept_body = Block::new();
@@ -1099,16 +1118,14 @@ impl Context {
// Flush the body of the `true` branch, to start emitting on the
// `false` branch
self.emit_flush(&mut accept_body);
self.emit_start();
self.emit_restart(&mut accept_body);
// Lower the `false` branch
let (mut reject, reject_meta) =
self.lower_expect_inner(stmt, parser, reject, pos, &mut reject_body)?;
// Flush the body of the `false` branch
self.emit_flush(&mut reject_body);
self.emit_start();
self.emit_restart(&mut reject_body);
// We need to do some custom implicit conversions since the two target expressions
// are in different bodies
@@ -1127,18 +1144,18 @@ impl Context {
self.conversion(&mut accept, accept_meta, reject_kind, reject_width)?;
// The expression belongs to the `true` branch so we need to flush to
// the respective body
self.emit_flush(&mut accept_body);
self.emit_end(&mut accept_body);
}
// Technically there's nothing to flush but we need to add some
// expressions that must not be emitted so instead of flushing,
// starting and flushing again, just make sure everything is
// flushed.
std::cmp::Ordering::Equal => self.emit_flush(body),
std::cmp::Ordering::Equal => self.emit_end(body),
std::cmp::Ordering::Greater => {
self.conversion(&mut reject, reject_meta, accept_kind, accept_width)?;
// The expression belongs to the `false` branch so we need to flush to
// the respective body
self.emit_flush(&mut reject_body);
self.emit_end(&mut reject_body);
}
}
}

View File

@@ -972,7 +972,7 @@ impl Parser {
match kind {
FunctionKind::Call(function) => {
ctx.emit_flush(body);
ctx.emit_end(body);
let result = if !is_void {
Some(ctx.add_expression(Expression::CallResult(function), meta, body))
@@ -995,8 +995,7 @@ impl Parser {
for (original, pointer) in proxy_writes {
let value = ctx.add_expression(Expression::Load { pointer }, meta, body);
ctx.emit_flush(body);
ctx.emit_start();
ctx.emit_restart(body);
body.push(
Statement::Store {

View File

@@ -436,8 +436,13 @@ impl<'ctx, 'qualifiers> DeclarationContext<'ctx, 'qualifiers> {
}
}
/// Emits all the expressions captured by the emitter and starts the emitter again
///
/// Alias to [`emit_restart`][emit_restart] with the declaration body
///
/// [emit_restart]: Context::emit_restart
#[inline]
fn flush_expressions(&mut self) {
self.ctx.emit_flush(self.body);
self.ctx.emit_start()
self.ctx.emit_restart(self.body);
}
}

View File

@@ -103,8 +103,7 @@ impl<'source> ParsingContext<'source> {
}
};
ctx.emit_flush(body);
ctx.emit_start();
ctx.emit_restart(body);
body.push(Statement::Return { value }, meta);
terminator.get_or_insert(body.len());
@@ -132,8 +131,7 @@ impl<'source> ParsingContext<'source> {
};
self.expect(parser, TokenValue::RightParen)?;
ctx.emit_flush(body);
ctx.emit_start();
ctx.emit_restart(body);
let mut accept = Block::new();
if let Some(more_meta) =
@@ -176,8 +174,7 @@ impl<'source> ParsingContext<'source> {
self.expect(parser, TokenValue::RightParen)?;
ctx.emit_flush(body);
ctx.emit_start();
ctx.emit_restart(body);
let mut cases = Vec::new();
@@ -301,8 +298,7 @@ impl<'source> ParsingContext<'source> {
&mut loop_body,
);
ctx.emit_flush(&mut loop_body);
ctx.emit_start();
ctx.emit_restart(&mut loop_body);
loop_body.push(
Statement::If {
@@ -359,8 +355,7 @@ impl<'source> ParsingContext<'source> {
&mut loop_body,
);
ctx.emit_flush(&mut loop_body);
ctx.emit_start();
ctx.emit_restart(&mut loop_body);
loop_body.push(
Statement::If {
@@ -427,8 +422,7 @@ impl<'source> ParsingContext<'source> {
let pointer = parser.add_local_var(ctx, &mut block, decl)?;
ctx.emit_flush(&mut block);
ctx.emit_start();
ctx.emit_restart(&mut block);
block.push(Statement::Store { pointer, value }, meta);
@@ -448,8 +442,7 @@ impl<'source> ParsingContext<'source> {
&mut block,
);
ctx.emit_flush(&mut block);
ctx.emit_start();
ctx.emit_restart(&mut block);
block.push(
Statement::If {