From 4fc03953d5891b7df03ccfcd96c592224e662592 Mon Sep 17 00:00:00 2001 From: John-John Tedro Date: Tue, 16 Jul 2024 17:41:46 +0200 Subject: [PATCH] rune: Allow empty values to be const constructed --- crates/rune/src/compile/ir/compiler.rs | 2 +- crates/rune/src/compile/ir/eval.rs | 12 +- crates/rune/src/compile/v1/assemble.rs | 4 +- crates/rune/src/modules/capture_io.rs | 2 +- crates/rune/src/modules/future.rs | 4 +- crates/rune/src/runtime/access.rs | 9 ++ crates/rune/src/runtime/const_value.rs | 2 +- crates/rune/src/runtime/generator.rs | 2 +- crates/rune/src/runtime/inst.rs | 2 +- crates/rune/src/runtime/shared.rs | 1 + crates/rune/src/runtime/stack.rs | 3 +- crates/rune/src/runtime/stream.rs | 2 +- crates/rune/src/runtime/tuple.rs | 2 +- crates/rune/src/runtime/value.rs | 145 +++++++++++++++++------- crates/rune/src/runtime/value/serde.rs | 2 +- crates/rune/src/runtime/vm.rs | 4 +- crates/rune/src/runtime/vm_execution.rs | 14 +-- 17 files changed, 140 insertions(+), 72 deletions(-) diff --git a/crates/rune/src/compile/ir/compiler.rs b/crates/rune/src/compile/ir/compiler.rs index 126f8ed4e..f9252eb43 100644 --- a/crates/rune/src/compile/ir/compiler.rs +++ b/crates/rune/src/compile/ir/compiler.rs @@ -239,7 +239,7 @@ fn lit(c: &mut Ctxt<'_, '_>, span: Span, hir: hir::Lit<'_>) -> compile::Result, span: Span, hir: &hir::ExprSeq<'_>) -> compile::Result { if hir.items.is_empty() { - let value = Value::empty().with_span(span)?; + let value = Value::unit().with_span(span)?; return Ok(ir::Ir::new(span, value)); } diff --git a/crates/rune/src/compile/ir/eval.rs b/crates/rune/src/compile/ir/eval.rs index 8caeba232..6a124bc7a 100644 --- a/crates/rune/src/compile/ir/eval.rs +++ b/crates/rune/src/compile/ir/eval.rs @@ -50,7 +50,7 @@ fn eval_ir_assign( .scopes .mut_target(&ir.target, move |t| ir.op.assign(ir, t, value))?; - Ok(Value::empty().with_span(ir)?) + Ok(Value::unit().with_span(ir)?) } fn eval_ir_binary( @@ -170,7 +170,7 @@ fn eval_ir_branches( return eval_ir_scope(branch, interp, used); } - Ok(Value::empty().with_span(ir)?) + Ok(Value::unit().with_span(ir)?) } fn eval_ir_call( @@ -214,7 +214,7 @@ fn eval_ir_decl( interp.budget.take(ir)?; let value = eval_ir(&ir.value, interp, used)?; interp.scopes.decl(&ir.name, value).with_span(ir)?; - Ok(Value::empty().with_span(ir)?) + Ok(Value::unit().with_span(ir)?) } fn eval_ir_loop( @@ -265,7 +265,7 @@ fn eval_ir_loop( Ok(value) } else { - Ok(Value::empty().with_span(ir)?) + Ok(Value::unit().with_span(ir)?) } } @@ -299,7 +299,7 @@ fn eval_ir_scope( let value = if let Some(last) = &ir.last { eval_ir(last, interp, used)? } else { - Value::empty().with_span(ir)? + Value::unit().with_span(ir)? }; interp.scopes.pop(guard).with_span(ir)?; @@ -314,7 +314,7 @@ fn eval_ir_set( interp.budget.take(ir)?; let value = eval_ir(&ir.value, interp, used)?; interp.scopes.set_target(&ir.target, value)?; - Ok(Value::empty().with_span(ir)?) + Ok(Value::unit().with_span(ir)?) } fn eval_ir_template( diff --git a/crates/rune/src/compile/v1/assemble.rs b/crates/rune/src/compile/v1/assemble.rs index 12690f022..a4aa908d2 100644 --- a/crates/rune/src/compile/v1/assemble.rs +++ b/crates/rune/src/compile/v1/assemble.rs @@ -1691,6 +1691,8 @@ fn expr_break<'a, 'hir>( converge!(expr(cx, hir, &mut needs)?, free(needs)); needs.free()?; + } else if let Some(out) = output { + cx.asm.push(Inst::unit(out), span)?; } // Drop loop temporaries. @@ -2980,8 +2982,8 @@ fn expr_loop<'a, 'hir>( cx.asm.push(Inst::unit(out), span)?; } - // NB: breaks produce their own value / perform their own cleanup. cx.asm.label(&break_label)?; + linear.free()?; cx.breaks.pop(); Ok(Asm::new(span, ())) diff --git a/crates/rune/src/modules/capture_io.rs b/crates/rune/src/modules/capture_io.rs index 5e295d4ae..29e3e05e0 100644 --- a/crates/rune/src/modules/capture_io.rs +++ b/crates/rune/src/modules/capture_io.rs @@ -117,6 +117,6 @@ fn dbg_impl( vm_try!(writeln!(o, "{:?}", value).map_err(VmError::panic)); } - vm_try!(out.store(stack, Value::empty)); + vm_try!(out.store(stack, Value::unit)); VmResult::Ok(()) } diff --git a/crates/rune/src/modules/future.rs b/crates/rune/src/modules/future.rs index 870ba97c5..230a38dfc 100644 --- a/crates/rune/src/modules/future.rs +++ b/crates/rune/src/modules/future.rs @@ -43,7 +43,7 @@ where }; futures.push(SelectFuture::new(index, future)); - vm_try!(results.try_push(vm_try!(Value::empty()))); + vm_try!(results.try_push(Value::empty())); } while !futures.is_empty() { @@ -85,7 +85,7 @@ where #[rune::function] async fn join(value: Value) -> VmResult { match &*vm_try!(value.borrow_kind_ref()) { - ValueKind::EmptyTuple => VmResult::Ok(vm_try!(Value::empty())), + ValueKind::EmptyTuple => VmResult::Ok(vm_try!(Value::unit())), ValueKind::Tuple(tuple) => VmResult::Ok(vm_try!( try_join_impl(tuple.iter(), tuple.len(), |vec| VmResult::Ok(vm_try!( Value::tuple(vec) diff --git a/crates/rune/src/runtime/access.rs b/crates/rune/src/runtime/access.rs index c59952a3e..e9c819be4 100644 --- a/crates/rune/src/runtime/access.rs +++ b/crates/rune/src/runtime/access.rs @@ -26,6 +26,13 @@ pub struct AccessError { } impl AccessError { + #[inline] + pub(crate) const fn empty() -> Self { + Self { + kind: AccessErrorKind::Empty, + } + } + #[inline] pub(crate) fn new(kind: AccessErrorKind) -> Self { Self { kind } @@ -35,6 +42,7 @@ impl AccessError { impl fmt::Display for AccessError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match &self.kind { + AccessErrorKind::Empty => write!(f, "Empty value"), AccessErrorKind::UnexpectedType { expected, actual } => write!( f, "Expected data of type `{expected}`, but found `{actual}`", @@ -98,6 +106,7 @@ impl From for AccessError { #[derive(Debug, PartialEq)] pub(crate) enum AccessErrorKind { + Empty, UnexpectedType { expected: RawStr, actual: RawStr }, NotAccessibleRef { error: NotAccessibleRef }, NotAccessibleMut { error: NotAccessibleMut }, diff --git a/crates/rune/src/runtime/const_value.rs b/crates/rune/src/runtime/const_value.rs index c4ef14bbc..5ce0ba3e7 100644 --- a/crates/rune/src/runtime/const_value.rs +++ b/crates/rune/src/runtime/const_value.rs @@ -44,7 +44,7 @@ impl ConstValue { /// otherwise. pub fn as_value(&self) -> alloc::Result { Ok(match self { - Self::EmptyTuple => Value::empty()?, + Self::EmptyTuple => Value::unit()?, Self::Byte(b) => Value::try_from(*b)?, Self::Char(c) => Value::try_from(*c)?, Self::Bool(b) => Value::try_from(*b)?, diff --git a/crates/rune/src/runtime/generator.rs b/crates/rune/src/runtime/generator.rs index 1ab54c66b..d2d85d927 100644 --- a/crates/rune/src/runtime/generator.rs +++ b/crates/rune/src/runtime/generator.rs @@ -59,7 +59,7 @@ where }; let state = if execution.is_resumed() { - vm_try!(execution.resume_with(vm_try!(Value::empty()))) + vm_try!(execution.resume_with(Value::empty())) } else { vm_try!(execution.resume()) }; diff --git a/crates/rune/src/runtime/inst.rs b/crates/rune/src/runtime/inst.rs index 3ec87b7b4..1a4822efd 100644 --- a/crates/rune/src/runtime/inst.rs +++ b/crates/rune/src/runtime/inst.rs @@ -1742,7 +1742,7 @@ impl InstValue { /// Convert into a value that can be pushed onto the stack. pub fn into_value(self) -> alloc::Result { match self { - Self::EmptyTuple => Value::empty(), + Self::EmptyTuple => Value::unit(), Self::Bool(v) => Value::try_from(v), Self::Byte(v) => Value::try_from(v), Self::Char(v) => Value::try_from(v), diff --git a/crates/rune/src/runtime/shared.rs b/crates/rune/src/runtime/shared.rs index 7624c42cc..aa5339ba6 100644 --- a/crates/rune/src/runtime/shared.rs +++ b/crates/rune/src/runtime/shared.rs @@ -17,6 +17,7 @@ use crate::alloc::{self, Box}; use crate::runtime::{Access, AccessError, BorrowMut, BorrowRef, RawAccessGuard, Snapshot}; /// A shared value. +#[repr(transparent)] pub(crate) struct Shared { inner: ptr::NonNull>, } diff --git a/crates/rune/src/runtime/stack.rs b/crates/rune/src/runtime/stack.rs index e91401878..a71b91ec3 100644 --- a/crates/rune/src/runtime/stack.rs +++ b/crates/rune/src/runtime/stack.rs @@ -190,8 +190,7 @@ impl Stack { return Ok(()); } - let empty = Value::empty()?; - self.stack.try_resize(self.top + size, empty)?; + self.stack.try_resize_with(self.top + size, Value::empty)?; Ok(()) } diff --git a/crates/rune/src/runtime/stream.rs b/crates/rune/src/runtime/stream.rs index 5793b22db..c13fc24fe 100644 --- a/crates/rune/src/runtime/stream.rs +++ b/crates/rune/src/runtime/stream.rs @@ -41,7 +41,7 @@ where }; let state = if execution.is_resumed() { - vm_try!(execution.async_resume_with(vm_try!(Value::empty())).await) + vm_try!(execution.async_resume_with(Value::empty()).await) } else { vm_try!(execution.async_resume().await) }; diff --git a/crates/rune/src/runtime/tuple.rs b/crates/rune/src/runtime/tuple.rs index c2513de3d..ee069821a 100644 --- a/crates/rune/src/runtime/tuple.rs +++ b/crates/rune/src/runtime/tuple.rs @@ -299,7 +299,7 @@ macro_rules! impl_tuple { impl ToValue for () { fn to_value(self) -> VmResult { - VmResult::Ok(vm_try!(Value::empty())) + VmResult::Ok(vm_try!(Value::unit())) } } }; diff --git a/crates/rune/src/runtime/value.rs b/crates/rune/src/runtime/value.rs index e39a74d13..43e5487cc 100644 --- a/crates/rune/src/runtime/value.rs +++ b/crates/rune/src/runtime/value.rs @@ -434,10 +434,16 @@ impl Ord for Rtti { } } +#[derive(Clone)] +enum ValueRepr { + Empty, + Value(Shared), +} + /// An entry on the stack. #[derive(Clone)] pub struct Value { - inner: Shared, + repr: ValueRepr, } impl Value { @@ -490,8 +496,13 @@ impl Value { T: Any, { let value = Shared::new(ValueKind::Any(AnyObj::from_ref(data)))?; - let (inner, guard) = Shared::into_drop_guard(value); - Ok((Self { inner }, guard)) + let (value, guard) = Shared::into_drop_guard(value); + Ok(( + Self { + repr: ValueRepr::Value(value), + }, + guard, + )) } /// Construct a value that wraps a mutable pointer. @@ -547,63 +558,75 @@ impl Value { { let obj = AnyObj::from_mut(data); let value = Shared::new(ValueKind::Any(obj))?; - let (inner, guard) = Shared::into_drop_guard(value); - Ok((Self { inner }, guard)) + let (value, guard) = Shared::into_drop_guard(value); + Ok(( + Self { + repr: ValueRepr::Value(value), + }, + guard, + )) } /// Test if the value is writable. pub fn is_writable(&self) -> bool { - self.inner.is_writable() + match self.repr { + ValueRepr::Empty => false, + ValueRepr::Value(ref value) => value.is_writable(), + } } /// Test if the value is readable. pub fn is_readable(&self) -> bool { - self.inner.is_readable() + match self.repr { + ValueRepr::Empty => false, + ValueRepr::Value(ref value) => value.is_readable(), + } } /// Get snapshot of value. /// /// The snapshot details how the value is currently being access. - #[allow(unused)] - pub fn snapshot(&self) -> Snapshot { - self.inner.snapshot() + pub fn snapshot(&self) -> Result { + Ok(self.as_value_kind()?.snapshot()) } - /// Construct an empty value. - pub(crate) fn empty() -> alloc::Result { + /// Construct a unit value. + pub(crate) fn unit() -> alloc::Result { Ok(Self { - inner: Shared::new(ValueKind::EmptyTuple)?, + repr: ValueRepr::Value(Shared::new(ValueKind::EmptyTuple)?), }) } - /// Test if the value is empty. - pub(crate) fn is_empty(&self) -> Result { - Ok(matches!(&*self.inner.borrow_ref()?, ValueKind::EmptyTuple)) + /// Construct an empty value. + pub(crate) const fn empty() -> Self { + Self { + repr: ValueRepr::Empty, + } } /// Take the kind of the value. pub(crate) fn take_kind(self) -> Result { - self.inner.take() + self.into_value_kind()?.take() } /// Borrow the kind of the value as a mutable reference. pub(crate) fn borrow_kind_mut(&self) -> Result, AccessError> { - self.inner.borrow_mut() + self.as_value_kind()?.borrow_mut() } /// Take the kind of the value as an owned mutable reference. pub(crate) fn into_kind_mut(self) -> Result, AccessError> { - self.inner.into_mut() + self.into_value_kind()?.into_mut() } /// Borrow the kind of the value as a reference. pub(crate) fn borrow_kind_ref(&self) -> Result, AccessError> { - self.inner.borrow_ref() + self.as_value_kind()?.borrow_ref() } /// Take the kind of the value as an owned reference. pub(crate) fn into_kind_ref(self) -> Result, AccessError> { - self.inner.into_ref() + self.into_value_kind()?.into_ref() } /// Format the value using the [Protocol::STRING_DISPLAY] protocol. @@ -681,7 +704,7 @@ impl Value { } pub(crate) fn clone_with(&self, caller: &mut impl ProtocolCaller) -> VmResult { - let inner = match &*vm_try!(self.inner.borrow_ref()) { + let kind = match &*vm_try!(self.borrow_kind_ref()) { ValueKind::EmptyTuple => ValueKind::EmptyTuple, ValueKind::Bool(value) => ValueKind::Bool(*value), ValueKind::Byte(value) => ValueKind::Byte(*value), @@ -729,7 +752,7 @@ impl Value { }; VmResult::Ok(Self { - inner: vm_try!(Shared::new(inner)), + repr: ValueRepr::Value(vm_try!(Shared::new(kind))), }) } @@ -753,7 +776,15 @@ impl Value { f: &mut Formatter, caller: &mut impl ProtocolCaller, ) -> VmResult<()> { - match &*vm_try!(self.inner.borrow_ref()) { + let value = match self.repr { + ValueRepr::Empty => { + vm_write!(f, ""); + return VmResult::Ok(()); + } + ValueRepr::Value(ref value) => value, + }; + + match &*vm_try!(value.borrow_ref()) { ValueKind::EmptyTuple => { vm_write!(f, "()"); } @@ -858,8 +889,8 @@ impl Value { if let VmResult::Ok(result) = result { vm_try!(<()>::from_value(result)); } else { - let type_info = vm_try!(self.type_info()); - vm_write!(f, "<{} object at {:p}>", type_info, self.inner); + let type_info = vm_try!(value.borrow_ref()).type_info(); + vm_write!(f, "<{} object at {:p}>", type_info, value); } } }; @@ -960,17 +991,21 @@ impl Value { /// Drop the interior value. pub(crate) fn drop(self) -> VmResult<()> { - drop(vm_try!(self.inner.take())); + if let ValueRepr::Value(value) = self.repr { + drop(vm_try!(value.take())); + } + VmResult::Ok(()) } /// Move the interior value. pub(crate) fn move_(self) -> VmResult { - let inner = vm_try!(self.inner.take()); - - VmResult::Ok(Value { - inner: vm_try!(Shared::new(inner)), - }) + match self.repr { + ValueRepr::Empty => VmResult::Ok(Self::empty()), + ValueRepr::Value(value) => VmResult::Ok(Value { + repr: ValueRepr::Value(vm_try!(Shared::new(vm_try!(value.take())))), + }), + } } /// Try to coerce value into a usize. @@ -991,7 +1026,7 @@ impl Value { /// Borrow the value of a string as a reference. #[inline] pub fn borrow_string_ref(&self) -> Result, RuntimeError> { - let result = BorrowRef::try_map(self.inner.borrow_ref()?, |kind| match kind { + let result = BorrowRef::try_map(self.borrow_kind_ref()?, |kind| match kind { ValueKind::String(string) => Some(string.as_str()), _ => None, }); @@ -1005,7 +1040,7 @@ impl Value { /// Take the current value as a string. #[inline] pub fn into_string(self) -> Result { - match self.inner.take()? { + match self.take_kind()? { ValueKind::String(string) => Ok(string), actual => Err(RuntimeError::expected::(actual.type_info())), } @@ -1015,7 +1050,7 @@ impl Value { #[doc(hidden)] #[inline] pub fn into_type_value(self) -> Result { - match self.inner.take()? { + match self.take_kind()? { ValueKind::EmptyTuple => Ok(TypeValue::EmptyTuple), ValueKind::Tuple(tuple) => Ok(TypeValue::Tuple(tuple)), ValueKind::Object(object) => Ok(TypeValue::Object(object)), @@ -1030,7 +1065,7 @@ impl Value { /// Coerce into a unit. #[inline] pub fn into_unit(&self) -> Result<(), RuntimeError> { - match *self.inner.borrow_ref()? { + match *self.borrow_kind_ref()? { ValueKind::EmptyTuple => Ok(()), ref actual => Err(RuntimeError::expected::<()>(actual.type_info())), } @@ -1339,7 +1374,7 @@ impl Value { /// environment. #[inline] pub fn into_future(self) -> VmResult { - let target = match vm_try!(self.inner.take()) { + let target = match vm_try!(self.take_kind()) { ValueKind::Future(future) => return VmResult::Ok(future), target => vm_try!(Value::try_from(target)), }; @@ -1414,7 +1449,7 @@ impl Value { where T: Any, { - let result = BorrowRef::try_map(self.inner.borrow_ref()?, |kind| match kind { + let result = BorrowRef::try_map(self.borrow_kind_ref()?, |kind| match kind { ValueKind::Any(any) => any.downcast_borrow_ref().ok(), _ => None, }); @@ -1431,7 +1466,7 @@ impl Value { where T: Any, { - let result = BorrowMut::try_map(self.inner.borrow_mut()?, |kind| match kind { + let result = BorrowMut::try_map(self.borrow_kind_mut()?, |kind| match kind { ValueKind::Any(any) => any.downcast_borrow_mut().ok(), _ => None, }); @@ -1448,7 +1483,9 @@ impl Value { where T: Any, { - let any = match self.inner.take()? { + let value = self.into_value_kind()?; + + let any = match value.take()? { ValueKind::Any(any) => any, actual => return Err(RuntimeError::expected_any(actual.type_info())), }; @@ -1470,12 +1507,12 @@ impl Value { /// One notable feature is that the type of a variant is its container /// *enum*, and not the type hash of the variant itself. pub fn type_hash(&self) -> Result { - Ok(self.inner.borrow_ref()?.type_hash()) + Ok(self.borrow_kind_ref()?.type_hash()) } /// Get the type information for the current value. pub fn type_info(&self) -> Result { - Ok(self.inner.borrow_ref()?.type_info()) + Ok(self.borrow_kind_ref()?.type_info()) } /// Perform a partial equality test between two values. @@ -2066,11 +2103,31 @@ impl Value { )), } } + + fn into_value_kind(self) -> Result, AccessError> { + match self.repr { + ValueRepr::Value(value) => Ok(value), + ValueRepr::Empty => Err(AccessError::empty()), + } + } + + fn as_value_kind(&self) -> Result<&Shared, AccessError> { + match &self.repr { + ValueRepr::Value(value) => Ok(value), + ValueRepr::Empty => Err(AccessError::empty()), + } + } } impl fmt::Debug for Value { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let snapshot = self.inner.snapshot(); + let snapshot = match &self.repr { + ValueRepr::Empty => { + write!(f, "")?; + return Ok(()); + } + ValueRepr::Value(value) => value.snapshot(), + }; if !snapshot.is_readable() { write!(f, "<{snapshot}>")?; @@ -2112,7 +2169,7 @@ impl TryFrom for Value { #[inline] fn try_from(kind: ValueKind) -> Result { Ok(Self { - inner: Shared::new(kind)?, + repr: ValueRepr::Value(Shared::new(kind)?), }) } } diff --git a/crates/rune/src/runtime/value/serde.rs b/crates/rune/src/runtime/value/serde.rs index 08377c9e2..000d79c6e 100644 --- a/crates/rune/src/runtime/value/serde.rs +++ b/crates/rune/src/runtime/value/serde.rs @@ -276,7 +276,7 @@ impl<'de> de::Visitor<'de> for VmVisitor { where E: de::Error, { - Value::empty().map_err(E::custom) + Value::unit().map_err(E::custom) } #[inline] diff --git a/crates/rune/src/runtime/vm.rs b/crates/rune/src/runtime/vm.rs index 09c6d79a6..ad693e15d 100644 --- a/crates/rune/src/runtime/vm.rs +++ b/crates/rune/src/runtime/vm.rs @@ -1721,7 +1721,7 @@ impl Vm { #[cfg_attr(feature = "bench", inline(never))] fn op_drop(&mut self, addr: InstAddress) -> VmResult<()> { - *vm_try!(self.stack.at_mut(addr)) = vm_try!(Value::empty()); + *vm_try!(self.stack.at_mut(addr)) = Value::empty(); VmResult::Ok(()) } @@ -2685,7 +2685,7 @@ impl Vm { #[cfg_attr(feature = "bench", inline(never))] fn op_is_unit(&mut self, addr: InstAddress, out: Output) -> VmResult<()> { let value = vm_try!(self.stack.at(addr)); - let is_unit = vm_try!(value.is_empty()); + let is_unit = matches!(&*vm_try!(value.borrow_kind_ref()), ValueKind::EmptyTuple); vm_try!(out.store(&mut self.stack, is_unit)); VmResult::Ok(()) } diff --git a/crates/rune/src/runtime/vm_execution.rs b/crates/rune/src/runtime/vm_execution.rs index 46fd6aa64..0cd9e7e31 100644 --- a/crates/rune/src/runtime/vm_execution.rs +++ b/crates/rune/src/runtime/vm_execution.rs @@ -207,7 +207,7 @@ where return VmResult::err(VmErrorKind::ExpectedExecutionState { actual: state }); }; - vm_try!(out.store(self.head.as_mut().stack_mut(), || VmResult::Ok(value))); + vm_try!(out.store(self.head.as_mut().stack_mut(), value)); self.inner_async_resume(None).await } @@ -228,7 +228,7 @@ where diagnostics: Option<&mut dyn VmDiagnostics>, ) -> VmResult { if let ExecutionState::Resumed(out) = self.state { - vm_try!(out.store(self.head.as_mut().stack_mut(), Value::empty)); + vm_try!(out.store(self.head.as_mut().stack_mut(), Value::unit)); } self.inner_async_resume(diagnostics).await @@ -262,7 +262,7 @@ where VmHalt::Yielded(addr, out) => { let value = match addr { Some(addr) => vm_try!(vm.stack().at(addr)).clone(), - None => vm_try!(Value::empty()), + None => vm_try!(Value::unit()), }; self.state = ExecutionState::Resumed(out); @@ -294,7 +294,7 @@ where return VmResult::err(VmErrorKind::ExpectedExecutionState { actual: state }); }; - vm_try!(out.store(self.head.as_mut().stack_mut(), || VmResult::Ok(value))); + vm_try!(out.store(self.head.as_mut().stack_mut(), value)); self.inner_resume(None) } @@ -320,7 +320,7 @@ where diagnostics: Option<&mut dyn VmDiagnostics>, ) -> VmResult { if let ExecutionState::Resumed(out) = replace(&mut self.state, ExecutionState::Suspended) { - vm_try!(out.store(self.head.as_mut().stack_mut(), Value::empty())); + vm_try!(out.store(self.head.as_mut().stack_mut(), Value::unit())); } self.inner_resume(diagnostics) @@ -351,7 +351,7 @@ where VmHalt::Yielded(addr, out) => { let value = match addr { Some(addr) => vm_try!(vm.stack().at(addr)).clone(), - None => vm_try!(Value::empty()), + None => vm_try!(Value::unit()), }; self.state = ExecutionState::Resumed(out); @@ -448,7 +448,7 @@ where let value = match addr { Some(addr) => vm_try!(self.head.as_ref().stack().at(addr)).clone(), - None => vm_try!(Value::empty()), + None => vm_try!(Value::unit()), }; debug_assert!(self.states.is_empty(), "Execution states should be empty");