Skip to content

Commit

Permalink
rune: Store GeneratorState in AnyObj instead of Mutable (relates #844)
Browse files Browse the repository at this point in the history
  • Loading branch information
udoprog committed Oct 30, 2024
1 parent a7f0f89 commit cf4516c
Show file tree
Hide file tree
Showing 9 changed files with 147 additions and 217 deletions.
51 changes: 2 additions & 49 deletions crates/rune/src/module/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ use crate::item::IntoComponent;
use crate::macros::{MacroContext, TokenStream};
use crate::module::DocFunction;
use crate::runtime::{
ConstConstruct, GeneratorState, InstAddress, MaybeTypeOf, Memory, Output, Protocol,
ToConstValue, TypeCheck, TypeHash, TypeInfo, TypeOf, Value, VmResult,
ConstConstruct, InstAddress, MaybeTypeOf, Memory, Output, Protocol, ToConstValue, TypeCheck,
TypeHash, TypeInfo, TypeOf, Value, VmResult,
};
use crate::{Hash, Item, ItemBuf};

Expand Down Expand Up @@ -353,53 +353,6 @@ impl Module {
Ok(())
}

/// Construct the type information for the `GeneratorState` type.
///
/// Registering this allows the given type to be used in Rune scripts when
/// referring to the `GeneratorState` type.
///
/// # Examples
///
/// This shows how to register the `GeneratorState` as
/// `nonstd::ops::GeneratorState`.
///
/// ```
/// use rune::Module;
///
/// let mut module = Module::with_crate_item("nonstd", ["ops"])?;
/// module.generator_state(["GeneratorState"])?;
///
/// Ok::<_, rune::support::Error>(())
pub fn generator_state<N>(
&mut self,
name: N,
) -> Result<InternalEnumMut<'_, GeneratorState>, ContextError>
where
N: IntoComponent,
{
let mut enum_ = InternalEnum::new(
"GeneratorState",
crate::runtime::static_type::GENERATOR_STATE,
);

// Note: these numeric variants are magic, and must simply match up with
// what's being used in the virtual machine implementation for these
// types.
enum_.variant(
"Complete",
TypeCheck::GeneratorState(0),
GeneratorState::Complete,
)?;

enum_.variant(
"Yielded",
TypeCheck::GeneratorState(1),
GeneratorState::Yielded,
)?;

self.install_internal_enum(name, enum_)
}

/// Construct type information for the `Option` type.
///
/// Registering this allows the given type to be used in Rune scripts when
Expand Down
2 changes: 1 addition & 1 deletion crates/rune/src/modules/ops/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ pub fn module() -> Result<Module, ContextError> {
}

{
m.generator_state(["GeneratorState"])?.docs(docstring! {
m.ty::<GeneratorState>()?.docs(docstring! {
/// Enum indicating the state of a generator.
})?;

Expand Down
21 changes: 20 additions & 1 deletion crates/rune/src/runtime/bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ use serde::ser;
use crate as rune;
use crate::alloc::prelude::*;
use crate::alloc::{self, Box, Vec};
use crate::runtime::{RawAnyGuard, Ref, UnsafeToRef, Value, VmResult};
use crate::Any;

use super::{IntoOutput, RawAnyGuard, Ref, UnsafeToRef, Value, VmResult};

/// A vector of bytes.
#[derive(Default, Any, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[rune(static_type = BYTES)]
Expand Down Expand Up @@ -440,3 +441,21 @@ impl<'de> de::Deserialize<'de> for Bytes {
deserializer.deserialize_bytes(Visitor)
}
}

impl TryFrom<&[u8]> for Value {
type Error = alloc::Error;

#[inline]
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
Value::new(Bytes::try_from(value)?)
}
}

impl IntoOutput for &[u8] {
type Output = Bytes;

#[inline]
fn into_output(self) -> VmResult<Self::Output> {
VmResult::Ok(vm_try!(Bytes::try_from(self)))
}
}
15 changes: 5 additions & 10 deletions crates/rune/src/runtime/generator_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,14 @@ use crate::Any;
/// # Ok::<_, rune::support::Error>(())
/// ```
#[derive(Any, Debug, TryClone)]
#[rune(builtin, static_type = GENERATOR_STATE)]
#[rune(static_type = GENERATOR_STATE)]
pub enum GeneratorState {
/// The generator yielded.
Yielded(Value),
#[rune(constructor)]
Yielded(#[rune(get, set)] Value),
/// The generator completed.
Complete(Value),
#[rune(constructor)]
Complete(#[rune(get, set)] Value),
}

impl GeneratorState {
Expand Down Expand Up @@ -97,10 +99,3 @@ impl GeneratorState {
}
}
}

from_value2!(
GeneratorState,
into_generator_state_ref,
into_generator_state_mut,
into_generator_state
);
14 changes: 9 additions & 5 deletions crates/rune/src/runtime/inst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,6 @@ pub enum TypeCheck {
/// A result type, and the specified variant index.
#[musli(packed)]
Result(usize),
/// A generator state type, and the specified variant index.
#[musli(packed)]
GeneratorState(usize),
}

impl fmt::Display for TypeCheck {
Expand All @@ -87,8 +84,6 @@ impl fmt::Display for TypeCheck {
Self::Option(..) => write!(fmt, "Option::None"),
Self::Result(0) => write!(fmt, "Result::Ok"),
Self::Result(..) => write!(fmt, "Result::Err"),
Self::GeneratorState(0) => write!(fmt, "GeneratorState::Yielded"),
Self::GeneratorState(..) => write!(fmt, "GeneratorState::Complete"),
}
}
}
Expand Down Expand Up @@ -1878,3 +1873,12 @@ where
fmt::Debug::fmt(&self.0, f)
}
}

impl IntoOutput for &str {
type Output = String;

#[inline]
fn into_output(self) -> VmResult<Self::Output> {
VmResult::Ok(vm_try!(String::try_from(self)))
}
}
7 changes: 7 additions & 0 deletions crates/rune/src/runtime/type_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,13 @@ impl fmt::Display for TypeInfo {
}
}

impl From<AnyTypeInfo> for TypeInfo {
#[inline]
fn from(value: AnyTypeInfo) -> Self {
Self::any_type_info(value)
}
}

/// Type information for the [`Any`][crate::Any] type.
#[derive(Debug, TryClone, Clone, Copy, PartialEq, Eq)]
#[try_clone(copy)]
Expand Down
67 changes: 10 additions & 57 deletions crates/rune/src/runtime/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ use crate::{Any, Hash};

use super::static_type;
use super::{
AccessError, AnyObj, AnyObjDrop, BorrowMut, BorrowRef, Bytes, CallResultOnly, ConstValue,
ConstValueKind, ControlFlow, DynGuardedArgs, EnvProtocolCaller, Format, Formatter, FromValue,
Function, Future, Generator, GeneratorState, IntoOutput, Iterator, MaybeTypeOf, Mut, Object,
OwnedTuple, Protocol, ProtocolCaller, RawAnyObjGuard, Ref, RuntimeError, Shared, Snapshot,
Stream, Type, TypeInfo, Variant, Vec, Vm, VmErrorKind, VmIntegerRepr, VmResult,
AccessError, AnyObj, AnyObjDrop, BorrowMut, BorrowRef, CallResultOnly, ConstValue,
ConstValueKind, DynGuardedArgs, EnvProtocolCaller, Formatter, FromValue, Function, Future,
Generator, IntoOutput, Iterator, MaybeTypeOf, Mut, Object, OwnedTuple, Protocol,
ProtocolCaller, RawAnyObjGuard, Ref, RuntimeError, Shared, Snapshot, Stream, Type, TypeInfo,
Variant, Vec, Vm, VmErrorKind, VmIntegerRepr, VmResult,
};
#[cfg(feature = "alloc")]
use super::{Hasher, Tuple};
Expand Down Expand Up @@ -428,9 +428,6 @@ impl Value {
Mutable::Object(value) => Mutable::Object(vm_try!(value.try_clone())),
Mutable::Stream(value) => Mutable::Stream(vm_try!(value.try_clone())),
Mutable::Generator(value) => Mutable::Generator(vm_try!(value.try_clone())),
Mutable::GeneratorState(value) => {
Mutable::GeneratorState(vm_try!(value.try_clone()))
}
Mutable::Option(value) => Mutable::Option(vm_try!(value.try_clone())),
Mutable::Result(value) => Mutable::Result(vm_try!(value.try_clone())),
Mutable::EmptyStruct(value) => Mutable::EmptyStruct(vm_try!(value.try_clone())),
Expand Down Expand Up @@ -512,9 +509,6 @@ impl Value {
Mutable::Generator(value) => {
vm_try!(vm_write!(f, "{value:?}"));
}
Mutable::GeneratorState(value) => {
vm_try!(vm_write!(f, "{value:?}"));
}
Mutable::Option(value) => {
vm_try!(vm_write!(f, "{value:?}"));
}
Expand Down Expand Up @@ -837,16 +831,6 @@ impl Value {
into_function,
}

into! {
/// Coerce into a [`GeneratorState`].
GeneratorState(GeneratorState),
into_generator_state_ref,
into_generator_state_mut,
borrow_generator_state_ref,
borrow_generator_state_mut,
into_generator_state,
}

into! {
/// Coerce into a [`Generator`].
Generator(Generator<Vm>),
Expand Down Expand Up @@ -1880,33 +1864,6 @@ impl TryFrom<&str> for Value {
}
}

impl IntoOutput for &str {
type Output = String;

#[inline]
fn into_output(self) -> VmResult<Self::Output> {
VmResult::Ok(vm_try!(String::try_from(self)))
}
}

impl TryFrom<&[u8]> for Value {
type Error = alloc::Error;

#[inline]
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
Value::new(Bytes::try_from(value)?)
}
}

impl IntoOutput for &[u8] {
type Output = Bytes;

#[inline]
fn into_output(self) -> VmResult<Self::Output> {
VmResult::Ok(vm_try!(Bytes::try_from(self)))
}
}

impl IntoOutput for Mutable {
type Output = Mutable;

Expand All @@ -1928,7 +1885,6 @@ inline_from! {

from! {
Function => Function,
GeneratorState => GeneratorState,
Vec => Vec,
EmptyStruct => EmptyStruct,
TupleStruct => TupleStruct,
Expand All @@ -1942,10 +1898,11 @@ from! {
}

any_from! {
String,
Bytes,
Format,
ControlFlow,
crate::alloc::String,
super::Bytes,
super::Format,
super::ControlFlow,
super::GeneratorState,
}

from_container! {
Expand Down Expand Up @@ -2077,8 +2034,6 @@ pub(crate) enum Mutable {
Stream(Stream<Vm>),
/// A stored generator.
Generator(Generator<Vm>),
/// Generator state.
GeneratorState(GeneratorState),
/// An empty value indicating nothing.
Option(Option<Value>),
/// A stored result in a slot.
Expand All @@ -2104,7 +2059,6 @@ impl Mutable {
Mutable::Future(..) => TypeInfo::static_type(static_type::FUTURE),
Mutable::Stream(..) => TypeInfo::static_type(static_type::STREAM),
Mutable::Generator(..) => TypeInfo::static_type(static_type::GENERATOR),
Mutable::GeneratorState(..) => TypeInfo::static_type(static_type::GENERATOR_STATE),
Mutable::Option(..) => TypeInfo::static_type(static_type::OPTION),
Mutable::Result(..) => TypeInfo::static_type(static_type::RESULT),
Mutable::Function(..) => TypeInfo::static_type(static_type::FUNCTION),
Expand All @@ -2127,7 +2081,6 @@ impl Mutable {
Mutable::Future(..) => static_type::FUTURE.hash,
Mutable::Stream(..) => static_type::STREAM.hash,
Mutable::Generator(..) => static_type::GENERATOR.hash,
Mutable::GeneratorState(..) => static_type::GENERATOR_STATE.hash,
Mutable::Result(..) => static_type::RESULT.hash,
Mutable::Option(..) => static_type::OPTION.hash,
Mutable::Function(..) => static_type::FUNCTION.hash,
Expand Down
3 changes: 0 additions & 3 deletions crates/rune/src/runtime/value/serde.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,6 @@ impl ser::Serialize for Value {
Mutable::Future(..) => Err(ser::Error::custom("cannot serialize futures")),
Mutable::Stream(..) => Err(ser::Error::custom("cannot serialize streams")),
Mutable::Generator(..) => Err(ser::Error::custom("cannot serialize generators")),
Mutable::GeneratorState(..) => {
Err(ser::Error::custom("cannot serialize generator states"))
}
Mutable::Function(..) => {
Err(ser::Error::custom("cannot serialize function pointers"))
}
Expand Down
Loading

0 comments on commit cf4516c

Please sign in to comment.