Refactor closure instantiation and inlining
This commit makes several changes related to how closures are handled: - **Dumper:** Removes redundant introspection of closure ASTs, as this is no longer relevant. - **Optimizer:** Updates `try_inline` to accept `ExecNode` for parameters and adds a check to ensure the `function_node` is a `Lambda` before attempting inlining. - **Environment:** Simplifies closure creation by passing an `ExecNode` for parameters and ensuring the correct `stack_size` is used. - **VM:** Adjusts `Closure` to store an `ExecNode` for parameters and updates `VM::unpack` to accept an `ExecNode`.
This commit is contained in:
@@ -1,6 +1,4 @@
|
||||
use crate::ast::compiler::bound_nodes::{BoundKind, Node};
|
||||
use crate::ast::types::Value;
|
||||
use crate::ast::vm::Closure;
|
||||
use std::fmt::Debug;
|
||||
|
||||
/// Human-readable AST dumper for the bound AST.
|
||||
@@ -38,28 +36,6 @@ impl Dumper {
|
||||
BoundKind::Nop => self.log("Nop", node),
|
||||
BoundKind::Constant(v) => {
|
||||
self.log(&format!("Constant: {}", v), node);
|
||||
// Introspect Closure AST if possible
|
||||
if let Value::Object(obj) = v
|
||||
&& let Some(closure) = obj.as_any().downcast_ref::<Closure>()
|
||||
{
|
||||
self.indent += 1;
|
||||
self.write_indent();
|
||||
self.output.push_str("--- Specialized Body ---\n");
|
||||
// We need to cast the inner TypedNode to the generic T required by visit.
|
||||
// Since Dumper is generic over T, but Closure stores TypedNode (where T = StaticType),
|
||||
// we can only fully dump if T is StaticType.
|
||||
// However, we can hack it by creating a new Dumper for the inner AST string.
|
||||
|
||||
// We can't call self.visit because types mismatch if T != StaticType.
|
||||
// So we just recursively dump to string and append.
|
||||
let inner_dump = Dumper::dump(&closure.function_node);
|
||||
for line in inner_dump.lines() {
|
||||
self.write_indent();
|
||||
self.output.push_str(line);
|
||||
self.output.push('\n');
|
||||
}
|
||||
self.indent -= 1;
|
||||
}
|
||||
}
|
||||
BoundKind::Get { addr, name } => {
|
||||
self.log(&format!("Get: {} ({:?})", name.name, addr), node)
|
||||
|
||||
@@ -334,19 +334,24 @@ impl Optimizer {
|
||||
}
|
||||
|
||||
path.inlining_depth += 1;
|
||||
let collapsed = self.try_inline(
|
||||
&closure.parameter_node,
|
||||
&arg_nodes,
|
||||
&closure.function_node,
|
||||
sub,
|
||||
path,
|
||||
Some(closure_sub),
|
||||
);
|
||||
path.inlining_depth -= 1;
|
||||
path.exit_lambda(&closure.function_node.identity);
|
||||
if let BoundKind::Lambda { params, .. } = &closure.function_node.kind {
|
||||
let collapsed = self.try_inline(
|
||||
params,
|
||||
&arg_nodes,
|
||||
&closure.function_node,
|
||||
sub,
|
||||
path,
|
||||
Some(closure_sub),
|
||||
);
|
||||
path.inlining_depth -= 1;
|
||||
path.exit_lambda(&closure.function_node.identity);
|
||||
|
||||
if let Some(res) = collapsed {
|
||||
return res;
|
||||
if let Some(res) = collapsed {
|
||||
return res;
|
||||
}
|
||||
} else {
|
||||
path.inlining_depth -= 1;
|
||||
path.exit_lambda(&closure.function_node.identity);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user