Skip to content

Commit

Permalink
rune: Store Function in AnyObj instead of Mutable (relates #844)
Browse files Browse the repository at this point in the history
  • Loading branch information
udoprog committed Nov 1, 2024
1 parent ba5218c commit ac461f3
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 152 deletions.
86 changes: 45 additions & 41 deletions crates/rune/src/modules/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ pub mod generator;
use core::cmp::Ordering;

use once_cell::sync::OnceCell;
use rune_alloc::hash_map::RandomState;
use rune::item;

use crate as rune;
use crate::alloc::hash_map::RandomState;
use crate::runtime::range::RangeIter;
use crate::runtime::range_from::RangeFromIter;
use crate::runtime::range_inclusive::RangeInclusiveIter;
Expand Down Expand Up @@ -71,16 +72,16 @@ pub fn module() -> Result<Module, ContextError> {
m.function_meta(RangeFrom::contains__meta)?;

m.function_meta(RangeFrom::partial_eq__meta)?;
m.implement_trait::<RangeFrom>(rune::item!(::std::cmp::PartialEq))?;
m.implement_trait::<RangeFrom>(item!(::std::cmp::PartialEq))?;

m.function_meta(RangeFrom::eq__meta)?;
m.implement_trait::<RangeFrom>(rune::item!(::std::cmp::Eq))?;
m.implement_trait::<RangeFrom>(item!(::std::cmp::Eq))?;

m.function_meta(RangeFrom::partial_cmp__meta)?;
m.implement_trait::<RangeFrom>(rune::item!(::std::cmp::PartialOrd))?;
m.implement_trait::<RangeFrom>(item!(::std::cmp::PartialOrd))?;

m.function_meta(RangeFrom::cmp__meta)?;
m.implement_trait::<RangeFrom>(rune::item!(::std::cmp::Ord))?;
m.implement_trait::<RangeFrom>(item!(::std::cmp::Ord))?;

iter!(RangeFromIter);
}
Expand All @@ -90,16 +91,16 @@ pub fn module() -> Result<Module, ContextError> {
m.function_meta(RangeFull::contains__meta)?;

m.function_meta(RangeFull::partial_eq__meta)?;
m.implement_trait::<RangeFull>(rune::item!(::std::cmp::PartialEq))?;
m.implement_trait::<RangeFull>(item!(::std::cmp::PartialEq))?;

m.function_meta(RangeFull::eq__meta)?;
m.implement_trait::<RangeFull>(rune::item!(::std::cmp::Eq))?;
m.implement_trait::<RangeFull>(item!(::std::cmp::Eq))?;

m.function_meta(RangeFull::partial_cmp__meta)?;
m.implement_trait::<RangeFull>(rune::item!(::std::cmp::PartialOrd))?;
m.implement_trait::<RangeFull>(item!(::std::cmp::PartialOrd))?;

m.function_meta(RangeFull::cmp__meta)?;
m.implement_trait::<RangeFull>(rune::item!(::std::cmp::Ord))?;
m.implement_trait::<RangeFull>(item!(::std::cmp::Ord))?;
}

{
Expand All @@ -109,16 +110,16 @@ pub fn module() -> Result<Module, ContextError> {
m.function_meta(RangeInclusive::contains__meta)?;

m.function_meta(RangeInclusive::partial_eq__meta)?;
m.implement_trait::<RangeInclusive>(rune::item!(::std::cmp::PartialEq))?;
m.implement_trait::<RangeInclusive>(item!(::std::cmp::PartialEq))?;

m.function_meta(RangeInclusive::eq__meta)?;
m.implement_trait::<RangeInclusive>(rune::item!(::std::cmp::Eq))?;
m.implement_trait::<RangeInclusive>(item!(::std::cmp::Eq))?;

m.function_meta(RangeInclusive::partial_cmp__meta)?;
m.implement_trait::<RangeInclusive>(rune::item!(::std::cmp::PartialOrd))?;
m.implement_trait::<RangeInclusive>(item!(::std::cmp::PartialOrd))?;

m.function_meta(RangeInclusive::cmp__meta)?;
m.implement_trait::<RangeInclusive>(rune::item!(::std::cmp::Ord))?;
m.implement_trait::<RangeInclusive>(item!(::std::cmp::Ord))?;

double_ended!(RangeInclusiveIter);
}
Expand All @@ -128,33 +129,33 @@ pub fn module() -> Result<Module, ContextError> {
m.function_meta(RangeToInclusive::contains__meta)?;

m.function_meta(RangeToInclusive::partial_eq__meta)?;
m.implement_trait::<RangeToInclusive>(rune::item!(::std::cmp::PartialEq))?;
m.implement_trait::<RangeToInclusive>(item!(::std::cmp::PartialEq))?;

m.function_meta(RangeToInclusive::eq__meta)?;
m.implement_trait::<RangeToInclusive>(rune::item!(::std::cmp::Eq))?;
m.implement_trait::<RangeToInclusive>(item!(::std::cmp::Eq))?;

m.function_meta(RangeToInclusive::partial_cmp__meta)?;
m.implement_trait::<RangeToInclusive>(rune::item!(::std::cmp::PartialOrd))?;
m.implement_trait::<RangeToInclusive>(item!(::std::cmp::PartialOrd))?;

m.function_meta(RangeToInclusive::cmp__meta)?;
m.implement_trait::<RangeToInclusive>(rune::item!(::std::cmp::Ord))?;
m.implement_trait::<RangeToInclusive>(item!(::std::cmp::Ord))?;
}

{
m.ty::<RangeTo>()?;
m.function_meta(RangeTo::contains__meta)?;

m.function_meta(RangeTo::partial_eq__meta)?;
m.implement_trait::<RangeTo>(rune::item!(::std::cmp::PartialEq))?;
m.implement_trait::<RangeTo>(item!(::std::cmp::PartialEq))?;

m.function_meta(RangeTo::eq__meta)?;
m.implement_trait::<RangeTo>(rune::item!(::std::cmp::Eq))?;
m.implement_trait::<RangeTo>(item!(::std::cmp::Eq))?;

m.function_meta(RangeTo::partial_cmp__meta)?;
m.implement_trait::<RangeTo>(rune::item!(::std::cmp::PartialOrd))?;
m.implement_trait::<RangeTo>(item!(::std::cmp::PartialOrd))?;

m.function_meta(RangeTo::cmp__meta)?;
m.implement_trait::<RangeTo>(rune::item!(::std::cmp::Ord))?;
m.implement_trait::<RangeTo>(item!(::std::cmp::Ord))?;
}

{
Expand All @@ -164,16 +165,16 @@ pub fn module() -> Result<Module, ContextError> {
m.function_meta(Range::contains__meta)?;

m.function_meta(Range::partial_eq__meta)?;
m.implement_trait::<Range>(rune::item!(::std::cmp::PartialEq))?;
m.implement_trait::<Range>(item!(::std::cmp::PartialEq))?;

m.function_meta(Range::eq__meta)?;
m.implement_trait::<Range>(rune::item!(::std::cmp::Eq))?;
m.implement_trait::<Range>(item!(::std::cmp::Eq))?;

m.function_meta(Range::partial_cmp__meta)?;
m.implement_trait::<Range>(rune::item!(::std::cmp::PartialOrd))?;
m.implement_trait::<Range>(item!(::std::cmp::PartialOrd))?;

m.function_meta(Range::cmp__meta)?;
m.implement_trait::<Range>(rune::item!(::std::cmp::Ord))?;
m.implement_trait::<Range>(item!(::std::cmp::Ord))?;

double_ended!(RangeIter);
}
Expand All @@ -182,29 +183,32 @@ pub fn module() -> Result<Module, ContextError> {
m.ty::<ControlFlow>()?;

m.function_meta(ControlFlow::partial_eq__meta)?;
m.implement_trait::<ControlFlow>(rune::item!(::std::cmp::PartialEq))?;
m.implement_trait::<ControlFlow>(item!(::std::cmp::PartialEq))?;

m.function_meta(ControlFlow::eq__meta)?;
m.implement_trait::<ControlFlow>(rune::item!(::std::cmp::Eq))?;
m.implement_trait::<ControlFlow>(item!(::std::cmp::Eq))?;

m.function_meta(ControlFlow::debug_fmt__meta)?;

m.function_meta(ControlFlow::clone__meta)?;
m.implement_trait::<ControlFlow>(rune::item!(::std::clone::Clone))?;
m.implement_trait::<ControlFlow>(item!(::std::clone::Clone))?;
}

m.ty::<Function>()?;
m.function_meta(Function::clone__meta)?;
m.implement_trait::<Function>(item!(::std::clone::Clone))?;
m.function_meta(Function::debug_fmt__meta)?;

m.function_meta(partial_eq)?;
m.function_meta(eq)?;
m.function_meta(partial_cmp)?;
m.function_meta(cmp)?;
m.function_meta(hash)?;
m.function_meta(partial_eq__meta)?;
m.function_meta(eq__meta)?;
m.function_meta(partial_cmp__meta)?;
m.function_meta(cmp__meta)?;
m.function_meta(hash__meta)?;

m.reexport(["Generator"], rune::item!(::std::ops::generator::Generator))?;
m.reexport(["Generator"], item!(::std::ops::generator::Generator))?;
m.reexport(
["GeneratorState"],
rune::item!(::std::ops::generator::GeneratorState),
item!(::std::ops::generator::GeneratorState),
)?;
Ok(m)
}
Expand All @@ -228,7 +232,7 @@ pub fn module() -> Result<Module, ContextError> {
/// assert!(partial_eq(1.0, 1.0));
/// assert!(!partial_eq(1.0, 2.0));
/// ```
#[rune::function]
#[rune::function(keep)]
fn partial_eq(lhs: Value, rhs: Value) -> VmResult<bool> {
Value::partial_eq(&lhs, &rhs)
}
Expand All @@ -251,7 +255,7 @@ fn partial_eq(lhs: Value, rhs: Value) -> VmResult<bool> {
/// assert!(eq(1.0, 1.0));
/// assert!(!eq(1.0, 2.0));
/// ```
#[rune::function]
#[rune::function(keep)]
fn eq(lhs: Value, rhs: Value) -> VmResult<bool> {
Value::eq(&lhs, &rhs)
}
Expand All @@ -278,7 +282,7 @@ fn eq(lhs: Value, rhs: Value) -> VmResult<bool> {
/// assert_eq!(partial_cmp(1.0, 2.0), Some(Ordering::Less));
/// assert_eq!(partial_cmp(1.0, f64::NAN), None);
/// ```
#[rune::function]
#[rune::function(keep)]
fn partial_cmp(lhs: Value, rhs: Value) -> VmResult<Option<Ordering>> {
Value::partial_cmp(&lhs, &rhs)
}
Expand Down Expand Up @@ -306,12 +310,12 @@ fn partial_cmp(lhs: Value, rhs: Value) -> VmResult<Option<Ordering>> {
/// assert_eq!(cmp(1, 1), Ordering::Equal);
/// assert_eq!(cmp(1, 2), Ordering::Less);
/// ```
#[rune::function]
#[rune::function(keep)]
fn cmp(lhs: Value, rhs: Value) -> VmResult<Ordering> {
Value::cmp(&lhs, &rhs)
}

/// Hashes the given value.
/// Hashes the given function.
///
/// For non-builtin types this uses the [`HASH`] protocol.
///
Expand All @@ -333,7 +337,7 @@ fn cmp(lhs: Value, rhs: Value) -> VmResult<Ordering> {
///
/// assert_eq!(hash([1, 2]), hash((1, 2)));
/// ```
#[rune::function]
#[rune::function(keep)]
fn hash(value: Value) -> VmResult<u64> {
let state = STATE.get_or_init(RandomState::new);
let mut hasher = Hasher::new_with(state);
Expand Down
103 changes: 48 additions & 55 deletions crates/rune/src/modules/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ use crate::alloc::string::FromUtf8Error;
use crate::alloc::{String, Vec};
use crate::compile::Named;
use crate::runtime::{
BorrowRefRepr, Bytes, Formatter, FromValue, Function, Hasher, Inline, MaybeTypeOf, Mutable,
Panic, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive, Ref, ToValue,
TypeOf, Value, VmErrorKind, VmResult,
Bytes, Formatter, FromValue, Function, Hasher, Inline, MaybeTypeOf, Panic, Range, RangeFrom,
RangeFull, RangeInclusive, RangeTo, RangeToInclusive, Ref, RefRepr, ToValue, TypeOf, Value,
VmErrorKind, VmResult,
};
use crate::{Any, ContextError, Module, TypeHash};

Expand Down Expand Up @@ -889,46 +889,40 @@ fn shrink_to_fit(s: &mut String) -> VmResult<()> {
/// [`split_whitespace`]: str::split_whitespace
#[rune::function(instance, deprecated = "Use String::split instead")]
fn split(this: Ref<str>, value: Value) -> VmResult<Value> {
let split = match vm_try!(value.borrow_ref_repr()) {
BorrowRefRepr::Inline(Inline::Char(c)) => {
vm_try!(rune::to_value(Split::new(this, *c)))
match vm_try!(value.as_ref_repr()) {
RefRepr::Inline(Inline::Char(c)) => {
VmResult::Ok(vm_try!(rune::to_value(Split::new(this, *c))))
}
BorrowRefRepr::Mutable(value) => match &*value {
Mutable::Function(ref f) => {
vm_try!(rune::to_value(Split::new(this, vm_try!(f.try_clone()))))
}
actual => {
return VmResult::err([
VmErrorKind::expected::<String>(actual.type_info()),
VmErrorKind::bad_argument(0),
])
}
},
BorrowRefRepr::Any(value) => match value.type_hash() {
RefRepr::Inline(value) => VmResult::err([
VmErrorKind::expected::<String>(value.type_info()),
VmErrorKind::bad_argument(0),
]),
RefRepr::Mutable(value) => VmResult::err([
VmErrorKind::expected::<String>(vm_try!(value.borrow_ref()).type_info()),
VmErrorKind::bad_argument(0),
]),
RefRepr::Any(value) => match value.type_hash() {
String::HASH => {
let s = vm_try!(value.borrow_ref::<String>());

vm_try!(rune::to_value(Split::new(
let split = vm_try!(rune::to_value(Split::new(
this,
vm_try!(String::try_from(s.as_str()))
)))
)));

VmResult::Ok(split)
}
_ => {
return VmResult::err([
VmErrorKind::expected::<String>(value.type_info()),
VmErrorKind::bad_argument(0),
]);
Function::HASH => {
let f = vm_try!(value.borrow_ref::<Function>());
let split = vm_try!(rune::to_value(Split::new(this, vm_try!(f.try_clone()))));
VmResult::Ok(split)
}
},
value => {
return VmResult::err([
_ => VmResult::err([
VmErrorKind::expected::<String>(value.type_info()),
VmErrorKind::bad_argument(0),
]);
}
};

VmResult::Ok(split)
]),
},
}
}

/// Splits the string on the first occurrence of the specified delimiter and
Expand All @@ -944,10 +938,27 @@ fn split(this: Ref<str>, value: Value) -> VmResult<Value> {
/// ```
#[rune::function(instance)]
fn split_once(this: &str, value: Value) -> VmResult<Option<(String, String)>> {
let outcome = match vm_try!(value.borrow_ref_repr()) {
BorrowRefRepr::Inline(Inline::Char(pat)) => this.split_once(*pat),
BorrowRefRepr::Mutable(value) => match &*value {
Mutable::Function(f) => {
let outcome = match vm_try!(value.as_ref_repr()) {
RefRepr::Inline(Inline::Char(pat)) => this.split_once(*pat),
RefRepr::Inline(value) => {
return VmResult::err([
VmErrorKind::expected::<String>(value.type_info()),
VmErrorKind::bad_argument(0),
]);
}
RefRepr::Mutable(value) => {
return VmResult::err([
VmErrorKind::expected::<String>(vm_try!(value.borrow_ref()).type_info()),
VmErrorKind::bad_argument(0),
]);
}
RefRepr::Any(value) => match value.type_hash() {
String::HASH => {
let s = vm_try!(value.borrow_ref::<String>());
this.split_once(s.as_str())
}
Function::HASH => {
let f = vm_try!(value.borrow_ref::<Function>());
let mut err = None;

let outcome = this.split_once(|c: char| match f.call::<bool>((c,)) {
Expand All @@ -967,31 +978,13 @@ fn split_once(this: &str, value: Value) -> VmResult<Option<(String, String)>> {

outcome
}
actual => {
return VmResult::err([
VmErrorKind::expected::<String>(actual.type_info()),
VmErrorKind::bad_argument(0),
])
}
},
BorrowRefRepr::Any(value) => match value.type_hash() {
String::HASH => {
let s = vm_try!(value.borrow_ref::<String>());
this.split_once(s.as_str())
}
_ => {
return VmResult::err([
VmErrorKind::expected::<String>(value.type_info()),
VmErrorKind::bad_argument(0),
]);
}
},
ref actual => {
return VmResult::err([
VmErrorKind::expected::<String>(actual.type_info()),
VmErrorKind::bad_argument(0),
])
}
};

let Some((a, b)) = outcome else {
Expand Down
Loading

0 comments on commit ac461f3

Please sign in to comment.