Refactor VM to use trait objects for closures
The `CallFrame` struct and various VM methods now use `Rc<dyn Object>` to hold closures, allowing for more flexibility and avoiding unnecessary cloning. This change also addresses the performance concern regarding deep copies of closures, preferring `Rc<dyn Trait>` with local `downcast_ref` where appropriate. Additionally, a documentation note has been added to `gemini.md` regarding this performance preference in Rust.
This commit is contained in:
@@ -261,12 +261,13 @@ impl Environment {
|
||||
vec![],
|
||||
*positional_count,
|
||||
));
|
||||
let closure_obj: Rc<dyn crate::ast::types::Object> = closure;
|
||||
|
||||
return Rc::new(crate::ast::types::NativeFunction {
|
||||
purity: Purity::Impure,
|
||||
func: Rc::new(move |args| {
|
||||
let mut vm = VM::new(global_values.clone());
|
||||
let res = match vm.run_with_args(&closure, args) {
|
||||
let res = match vm.run_with_args(closure_obj.clone(), args) {
|
||||
Ok(v) => v,
|
||||
Err(e) => panic!("Myc Runtime Error: {}", e),
|
||||
};
|
||||
@@ -287,9 +288,9 @@ impl Environment {
|
||||
|
||||
let mut final_res = res;
|
||||
if let Value::Object(obj) = &final_res
|
||||
&& let Some(closure) = obj.as_any().downcast_ref::<crate::ast::vm::Closure>()
|
||||
&& obj.as_any().downcast_ref::<crate::ast::vm::Closure>().is_some()
|
||||
{
|
||||
final_res = match vm.run_with_args(closure, args) {
|
||||
final_res = match vm.run_with_args(obj.clone(), args) {
|
||||
Ok(v) => v,
|
||||
Err(e) => panic!("Myc Runtime Error (Closure): {}", e),
|
||||
};
|
||||
@@ -396,8 +397,8 @@ impl Environment {
|
||||
|
||||
while let Ok(Value::TailCallRequest(payload)) = result {
|
||||
let (next_obj, next_args) = *payload;
|
||||
if let Some(closure) = next_obj.as_any().downcast_ref::<crate::ast::vm::Closure>() {
|
||||
result = vm.run_with_args_observed(&mut observer, closure, next_args);
|
||||
if next_obj.as_any().downcast_ref::<crate::ast::vm::Closure>().is_some() {
|
||||
result = vm.run_with_args_observed(&mut observer, next_obj, next_args);
|
||||
} else {
|
||||
result = Err(format!(
|
||||
"Tail call target is not a closure: {}",
|
||||
|
||||
Reference in New Issue
Block a user