Skip to content

Commit

Permalink
rune: Store Vec 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 a122ec7 commit 9d3b87e
Show file tree
Hide file tree
Showing 9 changed files with 298 additions and 250 deletions.
152 changes: 93 additions & 59 deletions crates/rune/src/compile/ir/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ use crate::compile::meta;
use crate::compile::{self, IrErrorKind, ItemId, ModId, WithSpan};
use crate::hir;
use crate::query::{Query, Used};
use crate::runtime::{BorrowRefRepr, ConstValue, Mutable, Object, OwnedTuple, RefRepr, Value};
use crate::runtime::{
self, BorrowRefRepr, ConstValue, Mutable, Object, OwnedTuple, RefRepr, Value,
};
use crate::TypeHash;

/// The interpreter that executed [Ir][crate::ir::Ir].
pub struct Interpreter<'a, 'arena> {
Expand Down Expand Up @@ -224,11 +227,6 @@ impl ir::Scopes {
match target {
BorrowRefRepr::Mutable(value) => {
match &*value {
Mutable::Vec(vec) => {
if let Some(value) = vec.get(*index) {
return Ok(value.clone());
}
}
Mutable::Tuple(tuple) => {
if let Some(value) = tuple.get(*index) {
return Ok(value.clone());
Expand All @@ -242,11 +240,26 @@ impl ir::Scopes {
}
};
}
actual => {
BorrowRefRepr::Any(value) => match value.type_hash() {
runtime::Vec::HASH => {
let vec = value.borrow_ref::<runtime::Vec>().with_span(ir_target)?;

if let Some(value) = vec.get(*index) {
return Ok(value.clone());
}
}
_ => {
return Err(compile::Error::expected_type::<OwnedTuple>(
ir_target,
value.type_info(),
));
}
},
value => {
return Err(compile::Error::expected_type::<OwnedTuple>(
ir_target,
actual.type_info(),
))
value.type_info(),
));
}
}

Expand Down Expand Up @@ -300,35 +313,47 @@ impl ir::Scopes {
ir::IrTargetKind::Index(target, index) => {
let target = self.get_target(target)?;

let mut target = match target.as_ref_repr().with_span(ir_target)? {
RefRepr::Mutable(current) => current.borrow_mut().with_span(ir_target)?,
actual => {
match target.as_ref_repr().with_span(ir_target)? {
RefRepr::Inline(value) => {
return Err(compile::Error::expected_type::<OwnedTuple>(
ir_target,
actual.type_info().with_span(ir_target)?,
value.type_info(),
));
}
};
RefRepr::Mutable(current) => {
let mut mutable = current.borrow_mut().with_span(ir_target)?;

match &mut *target {
Mutable::Vec(vec) => {
if let Some(current) = vec.get_mut(*index) {
*current = value;
return Ok(());
}
match &mut *mutable {
Mutable::Tuple(tuple) => {
if let Some(current) = tuple.get_mut(*index) {
*current = value;
return Ok(());
}
}
value => {
return Err(compile::Error::expected_type::<OwnedTuple>(
ir_target,
value.type_info(),
));
}
};
}
Mutable::Tuple(tuple) => {
if let Some(current) = tuple.get_mut(*index) {
*current = value;
return Ok(());
RefRepr::Any(any) => match any.type_hash() {
runtime::Vec::HASH => {
let mut vec = any.borrow_mut::<runtime::Vec>().with_span(ir_target)?;

if let Some(current) = vec.get_mut(*index) {
*current = value;
return Ok(());
}
}
}
actual => {
return Err(compile::Error::expected_type::<OwnedTuple>(
ir_target,
actual.type_info(),
));
}
_ => {
return Err(compile::Error::expected_type::<OwnedTuple>(
ir_target,
any.type_info(),
));
}
},
};

Err(compile::Error::msg(ir_target, "missing index"))
Expand Down Expand Up @@ -382,40 +407,49 @@ impl ir::Scopes {
ir::IrTargetKind::Index(target, index) => {
let current = self.get_target(target)?;

let mut value = match current.as_ref_repr().with_span(ir_target)? {
RefRepr::Mutable(value) => value.borrow_mut().with_span(ir_target)?,
actual => {
return Err(compile::Error::expected_type::<OwnedTuple>(
ir_target,
actual.type_info().with_span(ir_target)?,
));
}
};
match current.as_ref_repr().with_span(ir_target)? {
RefRepr::Mutable(value) => {
let mut value = value.borrow_mut().with_span(ir_target)?;

match &mut *value {
Mutable::Vec(vec) => {
let value = vec.get_mut(*index).ok_or_else(|| {
compile::Error::new(
match &mut *value {
Mutable::Tuple(tuple) => {
let value = tuple.get_mut(*index).ok_or_else(|| {
compile::Error::new(
ir_target,
IrErrorKind::MissingIndex { index: *index },
)
})?;

op(value)
}
actual => Err(compile::Error::expected_type::<OwnedTuple>(
ir_target,
IrErrorKind::MissingIndex { index: *index },
)
})?;

op(value)
actual.type_info(),
)),
}
}
Mutable::Tuple(tuple) => {
let value = tuple.get_mut(*index).ok_or_else(|| {
compile::Error::new(
ir_target,
IrErrorKind::MissingIndex { index: *index },
)
})?;
RefRepr::Any(value) => match value.type_hash() {
runtime::Vec::HASH => {
let mut vec =
value.borrow_mut::<runtime::Vec>().with_span(ir_target)?;

op(value)
}
let value = vec.get_mut(*index).ok_or_else(|| {
compile::Error::new(
ir_target,
IrErrorKind::MissingIndex { index: *index },
)
})?;

op(value)
}
_ => Err(compile::Error::expected_type::<OwnedTuple>(
ir_target,
value.type_info(),
)),
},
actual => Err(compile::Error::expected_type::<OwnedTuple>(
ir_target,
actual.type_info(),
actual.type_info().with_span(ir_target)?,
)),
}
}
Expand Down
23 changes: 13 additions & 10 deletions crates/rune/src/modules/future.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
use crate as rune;
use crate::alloc::Vec;
use crate::runtime::{
BorrowRefRepr, Future, Inline, Mut, Mutable, RefRepr, SelectFuture, Value, VmErrorKind,
self, BorrowRefRepr, Future, Inline, Mut, Mutable, RefRepr, SelectFuture, Value, VmErrorKind,
VmResult,
};
use crate::{ContextError, Module};
use crate::{ContextError, Module, TypeHash};

/// Asynchronous computations.
#[rune::module(::std::future)]
Expand Down Expand Up @@ -106,7 +106,7 @@ async fn join(value: Value) -> VmResult<Value> {
Inline::Unit => VmResult::Ok(Value::unit()),
value => VmResult::err([
VmErrorKind::bad_argument(0),
VmErrorKind::expected::<crate::runtime::Vec>(value.type_info()),
VmErrorKind::expected::<runtime::Vec>(value.type_info()),
]),
},
BorrowRefRepr::Mutable(value) => match *value {
Expand All @@ -118,21 +118,24 @@ async fn join(value: Value) -> VmResult<Value> {

VmResult::Ok(vm_try!(result))
}
Mutable::Vec(ref vec) => {
ref value => VmResult::err([
VmErrorKind::bad_argument(0),
VmErrorKind::expected::<runtime::Vec>(value.type_info()),
]),
},
BorrowRefRepr::Any(value) => match value.type_hash() {
runtime::Vec::HASH => {
let vec = vm_try!(value.borrow_ref::<runtime::Vec>());
let result = try_join_impl(vec.iter(), vec.len(), |vec| {
VmResult::Ok(vm_try!(Value::vec(vec)))
})
.await;
VmResult::Ok(vm_try!(result))
}
ref value => VmResult::err([
_ => VmResult::err([
VmErrorKind::bad_argument(0),
VmErrorKind::expected::<crate::runtime::Vec>(value.type_info()),
VmErrorKind::expected::<runtime::Vec>(value.type_info()),
]),
},
BorrowRefRepr::Any(value) => VmResult::err([
VmErrorKind::bad_argument(0),
VmErrorKind::expected::<crate::runtime::Vec>(value.type_info()),
]),
}
}
4 changes: 2 additions & 2 deletions crates/rune/src/modules/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ pub fn module() -> Result<Module, ContextError> {
m.function_meta(index_get)?;
m.function_meta(index_set)?;
m.function_meta(resize)?;
m.function_meta(string_debug)?;
m.function_meta(string_debug__meta)?;

m.function_meta(clone__meta)?;
m.implement_trait::<Vec>(rune::item!(::std::clone::Clone))?;
Expand Down Expand Up @@ -612,7 +612,7 @@ fn resize(this: &mut Vec, new_len: usize, value: Value) -> VmResult<()> {
/// let vec = [1, 2, 3];
/// assert_eq!(format!("{:?}", vec), "[1, 2, 3]");
/// ```
#[rune::function(instance, protocol = STRING_DEBUG)]
#[rune::function(keep, instance, protocol = STRING_DEBUG)]
fn string_debug(this: &Vec, f: &mut Formatter) -> VmResult<()> {
Vec::string_debug_with(this, f, &mut EnvProtocolCaller)
}
Expand Down
38 changes: 17 additions & 21 deletions crates/rune/src/runtime/const_value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use serde::{Deserialize, Serialize};
use crate as rune;
use crate::alloc::prelude::*;
use crate::alloc::{self, HashMap};
use crate::runtime;
use crate::{Hash, TypeHash};

use super::{
Expand Down Expand Up @@ -130,18 +131,12 @@ impl ConstValueKind {
fn type_info(&self) -> TypeInfo {
match self {
ConstValueKind::Inline(value) => value.type_info(),
ConstValueKind::String(..) => {
TypeInfo::static_type(crate::runtime::static_type::STRING)
}
ConstValueKind::Bytes(..) => TypeInfo::static_type(crate::runtime::static_type::BYTES),
ConstValueKind::Vec(..) => TypeInfo::static_type(crate::runtime::static_type::VEC),
ConstValueKind::Tuple(..) => TypeInfo::static_type(crate::runtime::static_type::TUPLE),
ConstValueKind::Object(..) => {
TypeInfo::static_type(crate::runtime::static_type::OBJECT)
}
ConstValueKind::Option(..) => {
TypeInfo::static_type(crate::runtime::static_type::OPTION)
}
ConstValueKind::String(..) => TypeInfo::static_type(runtime::static_type::STRING),
ConstValueKind::Bytes(..) => TypeInfo::static_type(runtime::static_type::BYTES),
ConstValueKind::Vec(..) => TypeInfo::static_type(runtime::static_type::VEC),
ConstValueKind::Tuple(..) => TypeInfo::static_type(runtime::static_type::TUPLE),
ConstValueKind::Object(..) => TypeInfo::static_type(runtime::static_type::OBJECT),
ConstValueKind::Option(..) => TypeInfo::static_type(runtime::static_type::OPTION),
ConstValueKind::Struct(hash, ..) => TypeInfo::any_type_info(AnyTypeInfo::new(
RawStr::from_str("constant struct"),
*hash,
Expand Down Expand Up @@ -243,15 +238,6 @@ impl ConstValue {
Some(some) => Some(Box::try_new(Self::from_value_ref(some)?)?),
None => None,
}),
Mutable::Vec(ref vec) => {
let mut const_vec = Vec::try_with_capacity(vec.len())?;

for value in vec {
const_vec.try_push(Self::from_value_ref(value)?)?;
}

ConstValueKind::Vec(const_vec)
}
Mutable::Tuple(ref tuple) => {
let mut const_tuple = Vec::try_with_capacity(tuple.len())?;

Expand Down Expand Up @@ -287,6 +273,16 @@ impl ConstValue {
let s = value.borrow_ref::<Bytes>()?;
ConstValueKind::Bytes(s.try_to_owned()?)
}
runtime::Vec::HASH => {
let vec = value.borrow_ref::<runtime::Vec>()?;
let mut const_vec = Vec::try_with_capacity(vec.len())?;

for value in vec.iter() {
const_vec.try_push(Self::from_value_ref(value)?)?;
}

ConstValueKind::Vec(const_vec)
}
_ => {
return Err(RuntimeError::from(VmErrorKind::ConstNotSupported {
actual: value.type_info(),
Expand Down
Loading

0 comments on commit 9d3b87e

Please sign in to comment.