optimize: make all call single arg
to allow more aggressive optimization
This commit is contained in:
@@ -175,38 +175,27 @@ impl<'jit, 'vm> Value<'jit, 'vm> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn call(&self, vm: &'vm VM<'jit>, args: Vec<Self>) -> Result<Self> {
|
||||
pub fn call(&mut self, vm: &'vm VM<'jit>, arg: Self) -> Result<()> {
|
||||
use Value::*;
|
||||
match self {
|
||||
PrimOp(func) => func.call(vm, args),
|
||||
PartialPrimOp(func) => func.call(vm, args),
|
||||
func @ Value::Func(_) => {
|
||||
let mut iter = args.into_iter();
|
||||
let mut func = func.clone();
|
||||
while let Some(arg) = iter.next() {
|
||||
func = match func {
|
||||
PrimOp(func) => {
|
||||
return func.call(vm, [arg].into_iter().chain(iter).collect());
|
||||
}
|
||||
PartialPrimOp(func) => {
|
||||
return func.call(vm, [arg].into_iter().chain(iter).collect());
|
||||
}
|
||||
Func(func) => func.call(vm, arg)?,
|
||||
_ => todo!(),
|
||||
}
|
||||
}
|
||||
func.ok()
|
||||
}
|
||||
x @ Catchable(_) => x.clone().ok(),
|
||||
_ => todo!(),
|
||||
if matches!(arg, Value::Catchable(_)) {
|
||||
*self = arg;
|
||||
return Ok(());
|
||||
}
|
||||
*self = match self {
|
||||
PrimOp(func) => func.call(vm, arg),
|
||||
PartialPrimOp(func) => func.call(vm, arg),
|
||||
Value::Func(func) => func.call(vm, arg),
|
||||
Catchable(_) => return Ok(()),
|
||||
_ => todo!(),
|
||||
}?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn not(self) -> Self {
|
||||
pub fn not(&mut self) {
|
||||
use Const::*;
|
||||
match self {
|
||||
*self = match &*self {
|
||||
VmConst(Bool(bool)) => VmConst(Bool(!bool)),
|
||||
x @ Value::Catchable(_) => x,
|
||||
Value::Catchable(_) => return,
|
||||
_ => todo!(),
|
||||
}
|
||||
}
|
||||
@@ -257,12 +246,12 @@ impl<'jit, 'vm> Value<'jit, 'vm> {
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn neg(self) -> Self {
|
||||
pub fn neg(&mut self) {
|
||||
use Const::*;
|
||||
match self {
|
||||
*self = match &*self {
|
||||
VmConst(Int(int)) => VmConst(Int(-int)),
|
||||
VmConst(Float(float)) => VmConst(Float(-float)),
|
||||
x @ Value::Catchable(_) => x,
|
||||
Value::Catchable(_) => return,
|
||||
_ => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,22 +21,22 @@ impl PartialEq for PrimOp<'_, '_> {
|
||||
}
|
||||
|
||||
impl<'jit, 'vm> PrimOp<'jit, 'vm> {
|
||||
pub fn call(&self, vm: &'vm VM<'jit>, args: Vec<Value<'jit, 'vm>>) -> Result<Value<'jit, 'vm>> {
|
||||
if (args.len()) < self.arity {
|
||||
pub fn call(&self, vm: &'vm VM<'jit>, arg: Value<'jit, 'vm>) -> Result<Value<'jit, 'vm>> {
|
||||
let mut args = Vec::with_capacity(self.arity);
|
||||
args.push(arg);
|
||||
if self.arity > 1 {
|
||||
Value::PartialPrimOp(
|
||||
PartialPrimOp {
|
||||
name: self.name,
|
||||
arity: self.arity - args.len(),
|
||||
arity: self.arity - 1,
|
||||
args,
|
||||
func: self.func,
|
||||
}
|
||||
.into(),
|
||||
)
|
||||
.ok()
|
||||
} else if args.len() == self.arity {
|
||||
(self.func)(vm, args)
|
||||
} else {
|
||||
unimplemented!()
|
||||
(self.func)(vm, args)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -57,22 +57,18 @@ impl PartialEq for PartialPrimOp<'_, '_> {
|
||||
|
||||
impl<'jit: 'vm, 'vm> PartialPrimOp<'jit, 'vm> {
|
||||
pub fn call(
|
||||
self: &Rc<Self>,
|
||||
self: &mut Rc<Self>,
|
||||
vm: &'vm VM<'jit>,
|
||||
args: Vec<Value<'jit, 'vm>>,
|
||||
arg: Value<'jit, 'vm>,
|
||||
) -> Result<Value<'jit, 'vm>> {
|
||||
let len = args.len();
|
||||
let mut self_clone = self.clone();
|
||||
let self_mut = Rc::make_mut(&mut self_clone);
|
||||
self_mut.args.extend(args);
|
||||
self_mut.arity -= len;
|
||||
let self_mut = Rc::make_mut(self);
|
||||
self_mut.args.push(arg);
|
||||
self_mut.arity -= 1;
|
||||
if self_mut.arity > 0 {
|
||||
Value::PartialPrimOp(self_clone).ok()
|
||||
} else if self_mut.arity == 0 {
|
||||
Value::PartialPrimOp(self.clone()).ok()
|
||||
} else {
|
||||
let args = std::mem::take(&mut self_mut.args);
|
||||
(self.func)(vm, args)
|
||||
} else {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user