Refactor specializer to not fold scalars
The specializer now correctly identifies when a compiled value is a scalar and avoids folding it into a constant node. Instead, it updates the callee to the specialized version if it's an object. This ensures that scalar folding does not interfere with the program's execution.
This commit is contained in:
@@ -233,39 +233,21 @@ impl Specializer {
|
|||||||
self.cache
|
self.cache
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.insert(key, (compiled_val.clone(), ret_ty.clone()));
|
.insert(key, (compiled_val.clone(), ret_ty.clone()));
|
||||||
let flat_elements = match &new_args.kind {
|
|
||||||
BoundKind::Tuple { elements } => elements.clone(),
|
// Only replace the callee if the compiled value is actually a function/object.
|
||||||
_ => vec![Rc::new(new_args.clone())],
|
// If it's a scalar (like 30 from folding), we DON'T fold here.
|
||||||
};
|
// We keep the Call but update the callee to the specialized version if it's an object.
|
||||||
let flat_types = flat_elements
|
if let Value::Object(_) | Value::Function(_) = &compiled_val {
|
||||||
.iter()
|
let specialized_callee = self.make_constant_node(
|
||||||
.map(|e| e.ty.original.ty.clone())
|
compiled_val,
|
||||||
.collect();
|
StaticType::Function(Box::new(Signature {
|
||||||
let flattened_args = Node {
|
params: StaticType::Tuple(arg_types),
|
||||||
identity: new_args.identity.clone(),
|
ret: ret_ty.clone(),
|
||||||
kind: BoundKind::Tuple {
|
})),
|
||||||
elements: flat_elements,
|
&new_callee,
|
||||||
},
|
);
|
||||||
ty: NodeMetrics {
|
return (specialized_callee, new_args, ret_ty);
|
||||||
original: Rc::new(Node {
|
}
|
||||||
identity: new_args.identity.clone(),
|
|
||||||
kind: BoundKind::Tuple { elements: vec![] },
|
|
||||||
ty: StaticType::Tuple(flat_types),
|
|
||||||
}),
|
|
||||||
purity: new_args.ty.purity,
|
|
||||||
is_recursive: new_args.ty.is_recursive,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let specialized_callee = self.make_constant_node(
|
|
||||||
compiled_val,
|
|
||||||
StaticType::Function(Box::new(Signature {
|
|
||||||
params: flattened_args.ty.original.ty.clone(),
|
|
||||||
ret: ret_ty.clone(),
|
|
||||||
})),
|
|
||||||
&new_callee,
|
|
||||||
);
|
|
||||||
return (specialized_callee, flattened_args, ret_ty);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(new_callee, new_args, original_ty)
|
(new_callee, new_args, original_ty)
|
||||||
|
|||||||
+1
-1
@@ -783,7 +783,7 @@ impl VM {
|
|||||||
}
|
}
|
||||||
|
|
||||||
match &curr.kind {
|
match &curr.kind {
|
||||||
BoundKind::Constant(v) => self.stack.push(v.clone()),
|
BoundKind::Constant(v) if !O::ACTIVE => self.stack.push(v.clone()),
|
||||||
_ => {
|
_ => {
|
||||||
let val = self.eval_internal(obs, curr)?;
|
let val = self.eval_internal(obs, curr)?;
|
||||||
self.stack.push(val);
|
self.stack.push(val);
|
||||||
|
|||||||
Reference in New Issue
Block a user