Skip to content

Commit

Permalink
rune: Vm cleanup (#882)
Browse files Browse the repository at this point in the history
  • Loading branch information
udoprog authored Nov 5, 2024
1 parent 02e6344 commit 930d24d
Show file tree
Hide file tree
Showing 44 changed files with 1,571 additions and 1,487 deletions.
2 changes: 1 addition & 1 deletion book/src/field_functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ impl External {
}
let mut module = Module::new();
module.field_function(Protocol::GET, "field", External::field_get)?;
module.field_function(&Protocol::GET, "field", External::field_get)?;
```

Would allow for this in Rune:
Expand Down
4 changes: 2 additions & 2 deletions book/src/traits.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,9 @@ let mut m = Module::with_crate("std", ["iter"]);
let mut t = m.define_trait(["Iterator"])?;

t.handler(|cx| {
let next = cx.find(Protocol::NEXT)?;
let next = cx.find(&Protocol::NEXT)?;

let size_hint = cx.find_or_define(Protocol::SIZE_HINT, |_: Value| (0usize, None::<usize>))?;
let size_hint = cx.find_or_define(&Protocol::SIZE_HINT, |_: Value| (0usize, None::<usize>))?;

/* more methods */
Ok(())
Expand Down
17 changes: 6 additions & 11 deletions crates/rune-core/src/hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ impl fmt::Display for TooManyParameters {

impl core::error::Error for TooManyParameters {}

use crate::protocol::Protocol;

use crate::alloc;
use crate::alloc::clone::TryClone;

Expand Down Expand Up @@ -143,26 +141,23 @@ impl Hash {
/// Construct a hash to an instance function, where the instance is a
/// pre-determined type.
#[inline]
pub fn associated_function<N>(type_hash: Hash, name: N) -> Self
where
N: IntoHash,
{
pub fn associated_function(type_hash: impl IntoHash, name: impl IntoHash) -> Self {
let type_hash = type_hash.into_hash();
let name = name.into_hash();
Self(ASSOCIATED_FUNCTION_HASH ^ (type_hash.0 ^ name.0))
}

/// Construct a hash corresponding to a field function.
#[inline]
pub fn field_function<N>(protocol: Protocol, type_hash: Hash, name: N) -> Self
where
N: IntoHash,
{
pub fn field_function(protocol: impl IntoHash, type_hash: Hash, name: impl IntoHash) -> Self {
let protocol = protocol.into_hash();
Self::associated_function(Hash(type_hash.0 ^ protocol.0), name)
}

/// Construct an index function.
#[inline]
pub fn index_function(protocol: Protocol, type_hash: Hash, index: Hash) -> Self {
pub fn index_function(protocol: impl IntoHash, type_hash: Hash, index: Hash) -> Self {
let protocol = protocol.into_hash();
Self::associated_function(Hash(type_hash.0 ^ protocol.0), index)
}

Expand Down
10 changes: 9 additions & 1 deletion crates/rune-core/src/hash/into_hash.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::hash::Hash;
use crate::protocol::Protocol;

mod sealed {
use crate::hash::Hash;
Expand All @@ -9,7 +10,7 @@ mod sealed {

impl Sealed for &str {}
impl Sealed for Hash {}
impl Sealed for Protocol {}
impl Sealed for &Protocol {}
impl<T, const N: usize> Sealed for Params<T, N> {}
}

Expand All @@ -33,3 +34,10 @@ impl IntoHash for &str {
Hash::ident(self)
}
}

impl IntoHash for &Protocol {
#[inline]
fn into_hash(self) -> Hash {
self.hash
}
}
24 changes: 2 additions & 22 deletions crates/rune-core/src/protocol.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
use core::cmp;
use core::fmt;
use core::hash::Hasher;
use core::ops;

use crate as rune;
#[cfg(feature = "alloc")]
use crate::alloc;
use crate::alloc::prelude::*;
use crate::hash::IntoHash;
use crate::hash::{Hash, ToTypeHash};
use crate::item::ItemBuf;

/// A built in instance function.
#[derive(Debug, TryClone, Clone, Copy)]
#[try_clone(copy)]
#[derive(Debug)]
#[non_exhaustive]
pub struct Protocol {
/// The name of the builtin function.
Expand All @@ -36,14 +31,7 @@ pub struct Protocol {
pub doc: &'static [&'static str],
}

impl IntoHash for Protocol {
#[inline]
fn into_hash(self) -> Hash {
self.hash
}
}

impl ToTypeHash for Protocol {
impl ToTypeHash for &Protocol {
#[inline]
fn to_type_hash(&self) -> Hash {
self.hash
Expand All @@ -56,14 +44,6 @@ impl ToTypeHash for Protocol {
}
}

impl ops::Deref for Protocol {
type Target = Hash;

fn deref(&self) -> &Self::Target {
&self.hash
}
}

impl fmt::Display for Protocol {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.name)
Expand Down
6 changes: 3 additions & 3 deletions crates/rune-macros/src/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,7 @@ fn expand_enum_install_with(
}

let is_variant = quote! {
module.associated_function(#protocol::IS_VARIANT, |this: &Self, index: usize| {
module.associated_function(&#protocol::IS_VARIANT, |this: &Self, index: usize| {
match (this, index) {
#(#is_variant,)*
_ => false,
Expand All @@ -489,7 +489,7 @@ fn expand_enum_install_with(

for (field, matches) in field_fns {
installers.push(quote! {
module.field_function(#protocol::GET, #field, |this: &Self| {
module.field_function(&#protocol::GET, #field, |this: &Self| {
match this {
#(#matches,)*
_ => return #vm_result::err(
Expand All @@ -504,7 +504,7 @@ fn expand_enum_install_with(

for (index, matches) in index_fns {
installers.push(quote! {
module.index_function(#protocol::GET, #index, |this: &Self| {
module.index_function(&#protocol::GET, #index, |this: &Self| {
match this {
#(#matches,)*
_ => return #vm_result::err(
Expand Down
26 changes: 13 additions & 13 deletions crates/rune-macros/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,17 +272,17 @@ impl Context {
..
} = g;

let protocol_field = g.tokens.protocol(Protocol::$proto);
let protocol_field = g.tokens.protocol(&Protocol::$proto);

match target {
GenerateTarget::Named { field_ident, field_name } => {
if let Some(custom) = &protocol.custom {
quote_spanned! { field.span() =>
module.field_function(#protocol_field, #field_name, #custom)?;
module.field_function(&#protocol_field, #field_name, #custom)?;
}
} else {
quote_spanned! { field.span() =>
module.field_function(#protocol_field, #field_name, |s: &mut Self, value: #ty| {
module.field_function(&#protocol_field, #field_name, |s: &mut Self, value: #ty| {
s.#field_ident $op value;
})?;
}
Expand All @@ -291,11 +291,11 @@ impl Context {
GenerateTarget::Numbered { field_index } => {
if let Some(custom) = &protocol.custom {
quote_spanned! { field.span() =>
module.index_function(#protocol_field, #field_index, #custom)?;
module.index_function(&#protocol_field, #field_index, #custom)?;
}
} else {
quote_spanned! { field.span() =>
module.index_function(#protocol_field, #field_index, |s: &mut Self, value: #ty| {
module.index_function(&#protocol_field, #field_index, |s: &mut Self, value: #ty| {
s.#field_index $op value;
})?;
}
Expand Down Expand Up @@ -391,10 +391,10 @@ impl Context {
quote!(#vm_try!(#try_clone::try_clone(&s.#field_ident)))
};

let protocol = g.tokens.protocol(Protocol::GET);
let protocol = g.tokens.protocol(&Protocol::GET);

quote_spanned! { g.field.span() =>
module.field_function(#protocol, #field_name, |s: &Self| #vm_result::Ok(#access))?;
module.field_function(&#protocol, #field_name, |s: &Self| #vm_result::Ok(#access))?;
}
}
GenerateTarget::Numbered { field_index } => {
Expand All @@ -404,10 +404,10 @@ impl Context {
quote!(#vm_try!(#try_clone::try_clone(&s.#field_index)))
};

let protocol = g.tokens.protocol(Protocol::GET);
let protocol = g.tokens.protocol(&Protocol::GET);

quote_spanned! { g.field.span() =>
module.index_function(#protocol, #field_index, |s: &Self| #vm_result::Ok(#access))?;
module.index_function(&#protocol, #field_index, |s: &Self| #vm_result::Ok(#access))?;
}
}
}
Expand All @@ -427,19 +427,19 @@ impl Context {
..
} = g;

let protocol = g.tokens.protocol(Protocol::SET);
let protocol = g.tokens.protocol(&Protocol::SET);

match target {
GenerateTarget::Named { field_ident, field_name } => {
quote_spanned! { g.field.span() =>
module.field_function(#protocol, #field_name, |s: &mut Self, value: #ty| {
module.field_function(&#protocol, #field_name, |s: &mut Self, value: #ty| {
s.#field_ident = value;
})?;
}
}
GenerateTarget::Numbered { field_index } => {
quote_spanned! { g.field.span() =>
module.index_function(#protocol, #field_index, |s: &mut Self, value: #ty| {
module.index_function(&#protocol, #field_index, |s: &mut Self, value: #ty| {
s.#field_index = value;
})?;
}
Expand Down Expand Up @@ -939,7 +939,7 @@ pub(crate) struct Tokens {

impl Tokens {
/// Define a tokenstream for the specified protocol
pub(crate) fn protocol(&self, sym: Protocol) -> TokenStream {
pub(crate) fn protocol(&self, sym: &Protocol) -> TokenStream {
let mut stream = TokenStream::default();
self.protocol.to_tokens(&mut stream);
<Token![::]>::default().to_tokens(&mut stream);
Expand Down
12 changes: 2 additions & 10 deletions crates/rune-macros/src/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,11 +241,7 @@ impl Function {
attrs: Vec::new(),
lit: syn::Lit::Str(match &attrs.path {
Path::Protocol(protocol) => {
break 'out syn::Expr::Path(syn::ExprPath {
attrs: Vec::new(),
qself: None,
path: protocol.clone(),
})
break 'out syn::parse_quote!(&#protocol);
}
Path::None => name_string.clone(),
Path::Rename(last) => {
Expand All @@ -258,11 +254,7 @@ impl Function {
match &attrs.path {
Path::None => expr_lit(&self.sig.ident),
Path::Rename(last) => expr_lit(&last.ident),
Path::Protocol(protocol) => syn::Expr::Path(syn::ExprPath {
attrs: Vec::new(),
qself: None,
path: protocol.clone(),
}),
Path::Protocol(protocol) => syn::parse_quote!(&#protocol),
}
};

Expand Down
13 changes: 8 additions & 5 deletions crates/rune/src/compile/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,10 @@ impl TraitContext<'_> {
/// Find the given protocol function for the current type.
///
/// This requires that the function is defined.
pub fn find(&mut self, protocol: Protocol) -> Result<Arc<FunctionHandler>, ContextError> {
pub fn find(
&mut self,
protocol: &'static Protocol,
) -> Result<Arc<FunctionHandler>, ContextError> {
let name = protocol.to_instance()?;

let hash = name
Expand Down Expand Up @@ -115,7 +118,7 @@ impl TraitContext<'_> {
/// Find or define a protocol function.
pub fn find_or_define<A, F>(
&mut self,
protocol: Protocol,
protocol: &'static Protocol,
function: F,
) -> Result<Arc<FunctionHandler>, ContextError>
where
Expand Down Expand Up @@ -1004,7 +1007,7 @@ impl Context {
}

self.constants.try_insert(
Hash::associated_function(ty.hash, Protocol::INTO_TYPE_NAME),
Hash::associated_function(ty.hash, &Protocol::INTO_TYPE_NAME),
ConstValue::from(ty.item.try_to_string()?),
)?;

Expand All @@ -1030,7 +1033,7 @@ impl Context {
}
rune::module::ModuleItemKind::Function(f) => {
self.constants.try_insert(
Hash::associated_function(m.hash, Protocol::INTO_TYPE_NAME),
Hash::associated_function(m.hash, &Protocol::INTO_TYPE_NAME),
ConstValue::from(m.item.try_to_string()?),
)?;

Expand Down Expand Up @@ -1120,7 +1123,7 @@ impl Context {

if let Some((hash, item)) = &item {
self.constants.try_insert(
Hash::associated_function(*hash, Protocol::INTO_TYPE_NAME),
Hash::associated_function(*hash, &Protocol::INTO_TYPE_NAME),
ConstValue::from(item.try_to_string()?),
)?;

Expand Down
10 changes: 5 additions & 5 deletions crates/rune/src/compile/meta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -517,11 +517,11 @@ impl DocType {
#[non_exhaustive]
pub enum AssociatedKind {
/// A protocol function implemented on the type itself.
Protocol(Protocol),
Protocol(&'static Protocol),
/// A field function with the given protocol.
FieldFn(Protocol, Cow<'static, str>),
FieldFn(&'static Protocol, Cow<'static, str>),
/// An index function with the given protocol.
IndexFn(Protocol, usize),
IndexFn(&'static Protocol, usize),
/// The instance function refers to the given named instance fn.
Instance(Cow<'static, str>),
}
Expand All @@ -532,10 +532,10 @@ impl AssociatedKind {
match self {
Self::Protocol(protocol) => Hash::associated_function(instance_type, protocol.hash),
Self::IndexFn(protocol, index) => {
Hash::index_function(*protocol, instance_type, Hash::index(*index))
Hash::index_function(protocol.hash, instance_type, Hash::index(*index))
}
Self::FieldFn(protocol, field) => {
Hash::field_function(*protocol, instance_type, field.as_ref())
Hash::field_function(protocol.hash, instance_type, field.as_ref())
}
Self::Instance(name) => Hash::associated_function(instance_type, name.as_ref()),
}
Expand Down
Loading

0 comments on commit 930d24d

Please sign in to comment.