Refactor: Use Value::Closure enum variant
Previously, compiled closures were stored as `Value::Object` and then downcasted. This commit introduces a dedicated `Value::Closure` enum variant to represent compiled closures. This improves type safety and simplifies handling of closures throughout the compiler and VM. This change involves: - Updating type definitions to use `Value::Closure`. - Adjusting downcasting logic to directly access the `Closure` struct. - Modifying `run_with_args` and `run_with_args_observed` to expect `Value::Closure` for tail-call targets. - Refining the handling of closures in the `Optimizer` and `Inliner` for better type clarity.
This commit is contained in:
@@ -3,7 +3,7 @@ use crate::ast::nodes::{
|
||||
IdentifierBinding, LambdaBinding, Node, NodeKind, UpvalueIdx, VirtualId,
|
||||
};
|
||||
use crate::ast::types::{Purity, Value};
|
||||
use crate::ast::closure::Closure;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
@@ -343,9 +343,9 @@ impl Optimizer {
|
||||
}
|
||||
}
|
||||
|
||||
if let NodeKind::Constant(Value::Object(ref obj)) = callee_opt.kind
|
||||
if let NodeKind::Constant(Value::Closure(ref closure_rc)) = callee_opt.kind
|
||||
&& path.inlining_depth < 5
|
||||
&& let Some(closure) = obj.as_any().downcast_ref::<Closure>()
|
||||
&& let closure = closure_rc.as_ref()
|
||||
&& (closure.upvalues.is_empty()
|
||||
|| closure.function_node.ty.purity >= Purity::SideEffectFree)
|
||||
&& !closure.function_node.ty.is_recursive
|
||||
|
||||
@@ -2,7 +2,7 @@ use crate::ast::nodes::{
|
||||
Address, AnalyzedNode, IdentifierBinding, NodeKind, VirtualId,
|
||||
};
|
||||
use crate::ast::types::{Purity, Value};
|
||||
use crate::ast::closure::Closure;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashSet;
|
||||
use std::rc::Rc;
|
||||
@@ -35,12 +35,8 @@ impl<'a> Inliner<'a> {
|
||||
| Value::Keyword(_)
|
||||
| Value::Record(_, _)
|
||||
| Value::DateTime(_) => true,
|
||||
Value::Object(obj) => {
|
||||
if let Some(closure) = obj.as_any().downcast_ref::<Closure>() {
|
||||
closure.upvalues.is_empty() && !closure.function_node.ty.is_recursive
|
||||
} else {
|
||||
false
|
||||
}
|
||||
Value::Closure(closure_rc) => {
|
||||
closure_rc.upvalues.is_empty() && !closure_rc.function_node.ty.is_recursive
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
|
||||
@@ -3,7 +3,7 @@ use crate::ast::nodes::{
|
||||
NodeKind, VirtualId,
|
||||
};
|
||||
use crate::ast::types::{Identity, Value};
|
||||
use crate::ast::closure::Closure;
|
||||
|
||||
use std::collections::HashSet;
|
||||
|
||||
// --- PathTracker ---
|
||||
@@ -56,12 +56,10 @@ impl UsageInfo {
|
||||
self.collect(value);
|
||||
}
|
||||
NodeKind::Constant(v) => {
|
||||
if let Value::Object(obj) = v
|
||||
&& let Some(closure) = obj.as_any().downcast_ref::<Closure>()
|
||||
{
|
||||
if let Value::Closure(closure_rc) = v {
|
||||
self.used_identities
|
||||
.insert(closure.function_node.identity.clone());
|
||||
self.collect(&closure.function_node);
|
||||
.insert(closure_rc.function_node.identity.clone());
|
||||
self.collect(&closure_rc.function_node);
|
||||
}
|
||||
}
|
||||
NodeKind::Identifier { binding, .. } => {
|
||||
|
||||
Reference in New Issue
Block a user