feat(tvix/eval): track whether locals needs to be finalised
When encountering a deferred local upvalue, the compiler will now mark the corresponding local as needing a finaliser which makes it possible to emit the OpFinalise instruction for this stack slot a little bit down the line. Change-Id: I3962066f10fc6c6e1472722b8bdb415a811e0740 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6338 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
This commit is contained in:
parent
025a9a4a0a
commit
5c4e102ac8
2 changed files with 12 additions and 0 deletions
|
@ -844,6 +844,7 @@ impl Compiler {
|
||||||
// and can be finalised.
|
// and can be finalised.
|
||||||
if slot.unwrap() < idx.0 {
|
if slot.unwrap() < idx.0 {
|
||||||
self.chunk().push_op(OpCode::DataDeferredLocal(idx));
|
self.chunk().push_op(OpCode::DataDeferredLocal(idx));
|
||||||
|
self.mark_needs_finaliser(slot.unwrap());
|
||||||
} else {
|
} else {
|
||||||
self.chunk().push_op(OpCode::DataLocalIdx(idx));
|
self.chunk().push_op(OpCode::DataLocalIdx(idx));
|
||||||
}
|
}
|
||||||
|
@ -987,6 +988,7 @@ impl Compiler {
|
||||||
name,
|
name,
|
||||||
depth,
|
depth,
|
||||||
initialised: false,
|
initialised: false,
|
||||||
|
needs_finaliser: false,
|
||||||
node: Some(node),
|
node: Some(node),
|
||||||
phantom: false,
|
phantom: false,
|
||||||
used: false,
|
used: false,
|
||||||
|
@ -1002,6 +1004,7 @@ impl Compiler {
|
||||||
self.scope_mut().locals.push(Local {
|
self.scope_mut().locals.push(Local {
|
||||||
depth,
|
depth,
|
||||||
initialised: true,
|
initialised: true,
|
||||||
|
needs_finaliser: false,
|
||||||
name: "".into(),
|
name: "".into(),
|
||||||
node: None,
|
node: None,
|
||||||
phantom: true,
|
phantom: true,
|
||||||
|
@ -1014,6 +1017,11 @@ impl Compiler {
|
||||||
self.scope_mut().locals[local_idx].initialised = true;
|
self.scope_mut().locals[local_idx].initialised = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Mark local as needing a finaliser.
|
||||||
|
fn mark_needs_finaliser(&mut self, local_idx: usize) {
|
||||||
|
self.scope_mut().locals[local_idx].needs_finaliser = true;
|
||||||
|
}
|
||||||
|
|
||||||
fn resolve_upvalue(&mut self, ctx_idx: usize, name: &str) -> Option<UpvalueIdx> {
|
fn resolve_upvalue(&mut self, ctx_idx: usize, name: &str) -> Option<UpvalueIdx> {
|
||||||
if ctx_idx == 0 {
|
if ctx_idx == 0 {
|
||||||
// There can not be any upvalue at the outermost context.
|
// There can not be any upvalue at the outermost context.
|
||||||
|
|
|
@ -38,6 +38,10 @@ pub struct Local {
|
||||||
|
|
||||||
// Is this local known to have been used at all?
|
// Is this local known to have been used at all?
|
||||||
pub used: bool,
|
pub used: bool,
|
||||||
|
|
||||||
|
// Does this local need to be finalised after the enclosing scope
|
||||||
|
// is completely constructed?
|
||||||
|
pub needs_finaliser: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Local {
|
impl Local {
|
||||||
|
|
Loading…
Reference in a new issue