feat: add experimental tailcall vm backend
This commit is contained in:
@@ -2,8 +2,7 @@ use std::cmp::Ordering;
|
||||
|
||||
use gc_arena::{Gc, Mutation};
|
||||
|
||||
use crate::{BytecodeReader, NixNum, StepResult, StrictValue, VmError, Value};
|
||||
use crate::VmContextExt;
|
||||
use crate::{BytecodeReader, NixNum, StepResult, StrictValue, Value, VmContextExt, VmError};
|
||||
|
||||
impl<'gc> crate::Vm<'gc> {
|
||||
#[inline(always)]
|
||||
@@ -21,7 +20,10 @@ impl<'gc> crate::Vm<'gc> {
|
||||
}
|
||||
let rhs = self.pop_stack_forced();
|
||||
let lhs = self.pop_stack_forced();
|
||||
if let (Some(ls), Some(rs)) = (VmContextExt::get_string(ctx, lhs), VmContextExt::get_string(ctx, rhs)) {
|
||||
if let (Some(ls), Some(rs)) = (
|
||||
VmContextExt::get_string(ctx, lhs),
|
||||
VmContextExt::get_string(ctx, rhs),
|
||||
) {
|
||||
let ns = Gc::new(mc, crate::NixString::new(format!("{ls}{rs}")));
|
||||
self.push_stack(Value::new_gc(ns));
|
||||
return StepResult::Continue;
|
||||
@@ -300,7 +302,10 @@ impl<'gc> crate::Vm<'gc> {
|
||||
if lhs.is::<crate::Null>() && rhs.is::<crate::Null>() {
|
||||
return Ok(true);
|
||||
}
|
||||
if let (Some(a), Some(b)) = (VmContextExt::get_string(ctx, lhs), VmContextExt::get_string(ctx, rhs)) {
|
||||
if let (Some(a), Some(b)) = (
|
||||
VmContextExt::get_string(ctx, lhs),
|
||||
VmContextExt::get_string(ctx, rhs),
|
||||
) {
|
||||
return Ok(a == b);
|
||||
}
|
||||
if let (Some(a), Some(b)) = (lhs.as_gc::<crate::List>(), rhs.as_gc::<crate::List>()) {
|
||||
@@ -358,20 +363,21 @@ impl<'gc> crate::Vm<'gc> {
|
||||
if let (Some(a), Some(b)) = (get_num(lhs), get_num(rhs)) {
|
||||
let ord = match (a, b) {
|
||||
(NixNum::Int(a), NixNum::Int(b)) => a.cmp(&b),
|
||||
(NixNum::Float(a), NixNum::Float(b)) => {
|
||||
a.partial_cmp(&b).unwrap_or(Ordering::Less)
|
||||
(NixNum::Float(a), NixNum::Float(b)) => a.partial_cmp(&b).unwrap_or(Ordering::Less),
|
||||
(NixNum::Int(a), NixNum::Float(b)) => {
|
||||
(a as f64).partial_cmp(&b).unwrap_or(Ordering::Less)
|
||||
}
|
||||
(NixNum::Float(a), NixNum::Int(b)) => {
|
||||
a.partial_cmp(&(b as f64)).unwrap_or(Ordering::Less)
|
||||
}
|
||||
(NixNum::Int(a), NixNum::Float(b)) => (a as f64)
|
||||
.partial_cmp(&b)
|
||||
.unwrap_or(Ordering::Less),
|
||||
(NixNum::Float(a), NixNum::Int(b)) => a
|
||||
.partial_cmp(&(b as f64))
|
||||
.unwrap_or(Ordering::Less),
|
||||
};
|
||||
self.push_stack(Value::new_inline(pred(ord)));
|
||||
return Ok(());
|
||||
}
|
||||
if let (Some(a), Some(b)) = (VmContextExt::get_string(ctx, lhs), VmContextExt::get_string(ctx, rhs)) {
|
||||
if let (Some(a), Some(b)) = (
|
||||
VmContextExt::get_string(ctx, lhs),
|
||||
VmContextExt::get_string(ctx, rhs),
|
||||
) {
|
||||
self.push_stack(Value::new_inline(pred(a.cmp(b))));
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user