[oden] The big lifetime removal

It turns out that rust can't really reason about the relationship
between the runtime lifetime and the context lifetime in a way that is
actually usable. This removes the lifetime stuff in favor of reference
counting the runtime itself, via a block that we embed in the
pointer. This, I think, it the least worst option here.
This commit is contained in:
John Doty 2023-06-19 08:28:26 -07:00
parent 898b1fe129
commit 9f808cea31
10 changed files with 269 additions and 312 deletions

View file

@ -2,20 +2,18 @@ use super::{TryFromValue, TryIntoValue};
use crate::{ContextRef, Error, ValueRef, ValueResult};
use std::marker::PhantomData;
pub trait IntoRustFunctionResult<'r> {
fn into_res(self, ctx: &ContextRef<'r>) -> ValueResult<'r>;
pub trait IntoRustFunctionResult {
fn into_res(self, ctx: &ContextRef) -> ValueResult;
}
impl<'r, T: TryIntoValue<'r>> IntoRustFunctionResult<'r> for T {
fn into_res(self, ctx: &ContextRef<'r>) -> ValueResult<'r> {
impl<T: TryIntoValue> IntoRustFunctionResult for T {
fn into_res(self, ctx: &ContextRef) -> ValueResult {
self.try_into_value(ctx)
}
}
impl<'r, T: TryIntoValue<'r>, E: std::fmt::Display> IntoRustFunctionResult<'r>
for core::result::Result<T, E>
{
fn into_res(self, ctx: &ContextRef<'r>) -> ValueResult<'r> {
impl<T: TryIntoValue, E: std::fmt::Display> IntoRustFunctionResult for core::result::Result<T, E> {
fn into_res(self, ctx: &ContextRef) -> ValueResult {
match self {
Ok(v) => v.try_into_value(ctx),
Err(e) => Err(Error::RustFunctionError(e.to_string())),
@ -23,21 +21,21 @@ impl<'r, T: TryIntoValue<'r>, E: std::fmt::Display> IntoRustFunctionResult<'r>
}
}
pub trait RustFunction<'r, F> {
pub trait RustFunction<F> {
fn argument_count() -> usize;
fn call(&self, context: &ContextRef<'r>, args: &[&ValueRef<'r>]) -> ValueResult<'r>;
fn call(&self, context: &ContextRef, args: &[&ValueRef]) -> ValueResult;
}
impl<'r, R, F> RustFunction<'r, PhantomData<(&R, &F)>> for F
impl<R, F> RustFunction<PhantomData<(&R, &F)>> for F
where
R: IntoRustFunctionResult<'r>,
F: Fn(&ContextRef<'r>) -> R + Sized,
R: IntoRustFunctionResult,
F: Fn(&ContextRef) -> R + Sized,
{
fn argument_count() -> usize {
0
}
fn call(&self, context: &ContextRef<'r>, args: &[&ValueRef<'r>]) -> ValueResult<'r> {
fn call(&self, context: &ContextRef, args: &[&ValueRef]) -> ValueResult {
if args.len() != 0 {
return Err(Error::ArgumentCountMismatch {
expected: Self::argument_count(),
@ -50,17 +48,17 @@ where
}
}
impl<'r, R, A, F> RustFunction<'r, PhantomData<(&R, &A, &F)>> for F
impl<R, A, F> RustFunction<PhantomData<(&R, &A, &F)>> for F
where
R: IntoRustFunctionResult<'r>,
R: IntoRustFunctionResult,
A: TryFromValue,
F: Fn(&ContextRef<'r>, A) -> R + Sized,
F: Fn(&ContextRef, A) -> R + Sized,
{
fn argument_count() -> usize {
1
}
fn call(&self, context: &ContextRef<'r>, args: &[&ValueRef<'r>]) -> ValueResult<'r> {
fn call(&self, context: &ContextRef, args: &[&ValueRef]) -> ValueResult {
if args.len() != Self::argument_count() {
return Err(Error::ArgumentCountMismatch {
expected: Self::argument_count(),
@ -74,18 +72,18 @@ where
}
}
impl<'r, R, A, B, F> RustFunction<'r, PhantomData<(&R, &A, &B, &F)>> for F
impl<R, A, B, F> RustFunction<PhantomData<(&R, &A, &B, &F)>> for F
where
R: IntoRustFunctionResult<'r>,
R: IntoRustFunctionResult,
A: TryFromValue,
B: TryFromValue,
F: Fn(&ContextRef<'r>, A, B) -> R + Sized,
F: Fn(&ContextRef, A, B) -> R + Sized,
{
fn argument_count() -> usize {
2
}
fn call(&self, context: &ContextRef<'r>, args: &[&ValueRef<'r>]) -> ValueResult<'r> {
fn call(&self, context: &ContextRef, args: &[&ValueRef]) -> ValueResult {
if args.len() != Self::argument_count() {
return Err(Error::ArgumentCountMismatch {
expected: Self::argument_count(),
@ -100,19 +98,19 @@ where
}
}
impl<'r, R, A, B, C, F> RustFunction<'r, PhantomData<(&R, &A, &B, &C, &F)>> for F
impl<R, A, B, C, F> RustFunction<PhantomData<(&R, &A, &B, &C, &F)>> for F
where
R: IntoRustFunctionResult<'r>,
R: IntoRustFunctionResult,
A: TryFromValue,
B: TryFromValue,
C: TryFromValue,
F: Fn(&ContextRef<'r>, A, B, C) -> R + Sized,
F: Fn(&ContextRef, A, B, C) -> R + Sized,
{
fn argument_count() -> usize {
3
}
fn call(&self, context: &ContextRef<'r>, args: &[&ValueRef<'r>]) -> ValueResult<'r> {
fn call(&self, context: &ContextRef, args: &[&ValueRef]) -> ValueResult {
if args.len() != Self::argument_count() {
return Err(Error::ArgumentCountMismatch {
expected: Self::argument_count(),
@ -128,20 +126,20 @@ where
}
}
impl<'r, R, A, B, C, D, F> RustFunction<'r, PhantomData<(&R, &A, &B, &C, &D, &F)>> for F
impl<R, A, B, C, D, F> RustFunction<PhantomData<(&R, &A, &B, &C, &D, &F)>> for F
where
R: IntoRustFunctionResult<'r>,
R: IntoRustFunctionResult,
A: TryFromValue,
B: TryFromValue,
C: TryFromValue,
D: TryFromValue,
F: Fn(&ContextRef<'r>, A, B, C, D) -> R + Sized,
F: Fn(&ContextRef, A, B, C, D) -> R + Sized,
{
fn argument_count() -> usize {
4
}
fn call(&self, context: &ContextRef<'r>, args: &[&ValueRef<'r>]) -> ValueResult<'r> {
fn call(&self, context: &ContextRef, args: &[&ValueRef]) -> ValueResult {
if args.len() != Self::argument_count() {
return Err(Error::ArgumentCountMismatch {
expected: Self::argument_count(),
@ -158,21 +156,21 @@ where
}
}
impl<'r, R, A, B, C, D, E, F> RustFunction<'r, PhantomData<(&R, &A, &B, &C, &D, &E, &F)>> for F
impl<R, A, B, C, D, E, F> RustFunction<PhantomData<(&R, &A, &B, &C, &D, &E, &F)>> for F
where
R: IntoRustFunctionResult<'r>,
R: IntoRustFunctionResult,
A: TryFromValue,
B: TryFromValue,
C: TryFromValue,
D: TryFromValue,
E: TryFromValue,
F: Fn(&ContextRef<'r>, A, B, C, D, E) -> R + Sized,
F: Fn(&ContextRef, A, B, C, D, E) -> R + Sized,
{
fn argument_count() -> usize {
5
}
fn call(&self, context: &ContextRef<'r>, args: &[&ValueRef<'r>]) -> ValueResult<'r> {
fn call(&self, context: &ContextRef, args: &[&ValueRef]) -> ValueResult {
if args.len() != Self::argument_count() {
return Err(Error::ArgumentCountMismatch {
expected: Self::argument_count(),