Skip to content

Commit

Permalink
rune: Store Format in AnyObj instead of Mutable (relates #844)
Browse files Browse the repository at this point in the history
  • Loading branch information
udoprog committed Oct 28, 2024
1 parent 2bddc1a commit fc7ee77
Show file tree
Hide file tree
Showing 26 changed files with 472 additions and 451 deletions.
8 changes: 4 additions & 4 deletions crates/rune/src/cli/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use crate::cli::{
use crate::compile::FileSourceLoader;
use crate::doc::TestParams;
use crate::modules::capture_io::CaptureIo;
use crate::runtime::{Mutable, OwnedValue, Value, Vm, VmError, VmResult};
use crate::runtime::{Mutable, OwnedRepr, Value, Vm, VmError, VmResult};
use crate::termcolor::{Color, ColorSpec, WriteColor};
use crate::{Diagnostics, Hash, Item, ItemBuf, Source, Sources, Unit};

Expand Down Expand Up @@ -498,12 +498,12 @@ impl TestCase {
capture_io.drain_into(&mut self.output)?;

self.outcome = match result {
VmResult::Ok(v) => match v.take_value()? {
OwnedValue::Mutable(Mutable::Result(result)) => match result {
VmResult::Ok(v) => match v.take_repr()? {
OwnedRepr::Mutable(Mutable::Result(result)) => match result {
Ok(..) => Outcome::Ok,
Err(error) => Outcome::Err(error),
},
OwnedValue::Mutable(Mutable::Option(option)) => match option {
OwnedRepr::Mutable(Mutable::Option(option)) => match option {
Some(..) => Outcome::Ok,
None => Outcome::None,
},
Expand Down
18 changes: 9 additions & 9 deletions crates/rune/src/compile/ir/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::ast::{Span, Spanned};
use crate::compile::ir::{self};
use crate::compile::{self, WithSpan};
use crate::query::Used;
use crate::runtime::{Inline, Object, OwnedTuple, Value, ValueBorrowRef};
use crate::runtime::{BorrowRefRepr, Inline, Object, OwnedTuple, Value};
use crate::TypeHash;

/// The outcome of a constant evaluation.
Expand Down Expand Up @@ -72,11 +72,11 @@ fn eval_ir_binary(
let a = eval_ir(&ir.lhs, interp, used)?;
let b = eval_ir(&ir.rhs, interp, used)?;

let a = a.borrow_ref().with_span(ir)?;
let b = b.borrow_ref().with_span(ir)?;
let a = a.borrow_ref_repr().with_span(ir)?;
let b = b.borrow_ref_repr().with_span(ir)?;

match (a, b) {
(ValueBorrowRef::Inline(a), ValueBorrowRef::Inline(b)) => {
(BorrowRefRepr::Inline(a), BorrowRefRepr::Inline(b)) => {
let out = 'out: {
match (a, b) {
(Inline::Integer(a), Inline::Integer(b)) => match ir.op {
Expand Down Expand Up @@ -140,7 +140,7 @@ fn eval_ir_binary(

return Ok(Value::from(out));
}
(ValueBorrowRef::Any(a), ValueBorrowRef::Any(b)) => {
(BorrowRefRepr::Any(a), BorrowRefRepr::Any(b)) => {
let value = 'out: {
if let (String::HASH, String::HASH) = (a.type_hash(), b.type_hash()) {
let a = a.borrow_ref::<String>().with_span(span)?;
Expand Down Expand Up @@ -353,10 +353,10 @@ fn eval_ir_template(
}
ir::IrTemplateComponent::Ir(ir) => {
let const_value = eval_ir(ir, interp, used)?;
let value = const_value.borrow_ref().with_span(ir)?;
let value = const_value.borrow_ref_repr().with_span(ir)?;

match value {
ValueBorrowRef::Inline(value) => match value {
BorrowRefRepr::Inline(value) => match value {
Inline::Integer(integer) => {
write!(buf, "{integer}")?;
}
Expand All @@ -371,7 +371,7 @@ fn eval_ir_template(
return Err(EvalOutcome::not_const(ir));
}
},
ValueBorrowRef::Any(value) => match value.type_hash() {
BorrowRefRepr::Any(value) => match value.type_hash() {
String::HASH => {
let s = value.borrow_ref::<String>().with_span(ir)?;
buf.try_push_str(&s)?;
Expand All @@ -380,7 +380,7 @@ fn eval_ir_template(
return Err(EvalOutcome::not_const(ir));
}
},
ValueBorrowRef::Mutable(..) => {
BorrowRefRepr::Mutable(..) => {
return Err(EvalOutcome::not_const(ir));
}
}
Expand Down
26 changes: 13 additions & 13 deletions crates/rune/src/compile/ir/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::compile::meta;
use crate::compile::{self, IrErrorKind, ItemId, ModId, WithSpan};
use crate::hir;
use crate::query::{Query, Used};
use crate::runtime::{ConstValue, Mutable, Object, OwnedTuple, Value, ValueBorrowRef, ValueRef};
use crate::runtime::{BorrowRefRepr, ConstValue, Mutable, Object, OwnedTuple, RefRepr, Value};

/// The interpreter that executed [Ir][crate::ir::Ir].
pub struct Interpreter<'a, 'arena> {
Expand Down Expand Up @@ -184,10 +184,10 @@ impl ir::Scopes {
ir::IrTargetKind::Name(name) => Ok(self.get_name(name, ir_target)?.clone()),
ir::IrTargetKind::Field(ir_target, field) => {
let value = self.get_target(ir_target)?;
let value = value.borrow_ref().with_span(ir_target)?;
let value = value.borrow_ref_repr().with_span(ir_target)?;

let value = match value {
ValueBorrowRef::Mutable(value) => value,
BorrowRefRepr::Mutable(value) => value,
actual => {
return Err(compile::Error::expected_type::<OwnedTuple>(
ir_target,
Expand Down Expand Up @@ -219,10 +219,10 @@ impl ir::Scopes {
}
ir::IrTargetKind::Index(target, index) => {
let value = self.get_target(target)?;
let target = value.borrow_ref().with_span(ir_target)?;
let target = value.borrow_ref_repr().with_span(ir_target)?;

match target {
ValueBorrowRef::Mutable(value) => {
BorrowRefRepr::Mutable(value) => {
match &*value {
Mutable::Vec(vec) => {
if let Some(value) = vec.get(*index) {
Expand Down Expand Up @@ -272,8 +272,8 @@ impl ir::Scopes {
ir::IrTargetKind::Field(target, field) => {
let target = self.get_target(target)?;

let mut target = match target.value_ref().with_span(ir_target)? {
ValueRef::Mutable(current) => current.borrow_mut().with_span(ir_target)?,
let mut target = match target.as_ref_repr().with_span(ir_target)? {
RefRepr::Mutable(current) => current.borrow_mut().with_span(ir_target)?,
actual => {
return Err(compile::Error::expected_type::<Object>(
ir_target,
Expand All @@ -300,8 +300,8 @@ impl ir::Scopes {
ir::IrTargetKind::Index(target, index) => {
let target = self.get_target(target)?;

let mut target = match target.value_ref().with_span(ir_target)? {
ValueRef::Mutable(current) => current.borrow_mut().with_span(ir_target)?,
let mut target = match target.as_ref_repr().with_span(ir_target)? {
RefRepr::Mutable(current) => current.borrow_mut().with_span(ir_target)?,
actual => {
return Err(compile::Error::expected_type::<OwnedTuple>(
ir_target,
Expand Down Expand Up @@ -350,8 +350,8 @@ impl ir::Scopes {
ir::IrTargetKind::Field(target, field) => {
let value = self.get_target(target)?;

let mut value = match value.value_ref().with_span(ir_target)? {
ValueRef::Mutable(value) => value.borrow_mut().with_span(ir_target)?,
let mut value = match value.as_ref_repr().with_span(ir_target)? {
RefRepr::Mutable(value) => value.borrow_mut().with_span(ir_target)?,
actual => {
return Err(compile::Error::expected_type::<Object>(
ir_target,
Expand Down Expand Up @@ -382,8 +382,8 @@ impl ir::Scopes {
ir::IrTargetKind::Index(target, index) => {
let current = self.get_target(target)?;

let mut value = match current.value_ref().with_span(ir_target)? {
ValueRef::Mutable(value) => value.borrow_mut().with_span(ir_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,
Expand Down
2 changes: 1 addition & 1 deletion crates/rune/src/compile/v1/assemble.rs
Original file line number Diff line number Diff line change
Expand Up @@ -984,7 +984,7 @@ fn block_without_scope<'a, 'hir>(
Ok(Asm::new(hir, ()))
}

/// Assemble #[builtin] format_args!(...) macro.
/// Assemble #[builtin] format!(...) macro.
#[instrument_ast(span = format)]
fn builtin_format<'a, 'hir>(
cx: &mut Ctxt<'a, 'hir, '_>,
Expand Down
4 changes: 1 addition & 3 deletions crates/rune/src/exported_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,7 @@ macro_rules! vm_write {
($($tt:tt)*) => {
match core::write!($($tt)*) {
Ok(()) => $crate::runtime::VmResult::Ok(()),
Err(err) => {
return $crate::runtime::VmResult::Err($crate::runtime::VmError::from(err));
}
Err(err) => $crate::runtime::VmResult::Err($crate::runtime::VmError::from(err)),
}
};
}
Expand Down
70 changes: 61 additions & 9 deletions crates/rune/src/modules/fmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ use core::fmt;

use crate as rune;
use crate::alloc::fmt::TryWrite;
use crate::alloc::prelude::*;
use crate::compile;
use crate::macros::{FormatArgs, MacroContext, TokenStream};
use crate::parse::Parser;
use crate::runtime::{Format, Formatter, VmResult};
use crate::runtime::{EnvProtocolCaller, Format, Formatter, VmResult};
use crate::{ContextError, Module};

/// Formatting text.
Expand All @@ -23,14 +24,20 @@ use crate::{ContextError, Module};
/// ```
#[rune::module(::std::fmt)]
pub fn module() -> Result<Module, ContextError> {
let mut module = Module::from_meta(self::module_meta)?.with_unique("std::fmt");

module.ty::<Format>()?;
module.ty::<Formatter>()?;
module.ty::<fmt::Error>()?;
module.function_meta(fmt_error_string_display)?;
module.macro_meta(format)?;
Ok(module)
let mut m = Module::from_meta(self::module_meta)?.with_unique("std::fmt");

m.ty::<Formatter>()?;
m.ty::<fmt::Error>()?;
m.function_meta(fmt_error_string_display)?;
m.macro_meta(format)?;

m.ty::<Format>()?;
m.function_meta(format_string_display__meta)?;
m.function_meta(format_string_debug__meta)?;
m.function_meta(format_clone__meta)?;
m.implement_trait::<Format>(rune::item!(::std::clone::Clone))?;

Ok(m)
}

#[rune::function(instance, protocol = STRING_DISPLAY)]
Expand Down Expand Up @@ -58,3 +65,48 @@ pub(crate) fn format(
let expanded = args.expand(cx)?;
Ok(expanded.into_token_stream(cx)?)
}

/// Write a display representation of a format specification.
///
/// # Examples
///
/// ```rune
/// let value = #[builtin] format!("Hello", fill = '0', width = 10);
/// assert_eq!(format!("{value}"), "Hello00000");
/// ```
#[rune::function(keep, instance, protocol = STRING_DISPLAY)]
fn format_string_display(format: &Format, f: &mut Formatter) -> VmResult<()> {
VmResult::Ok(vm_try!(format.spec.format(
&format.value,
f,
&mut EnvProtocolCaller
)))
}

/// Write a debug representation of a format specification.
///
/// # Examples
///
/// ```rune
/// let value = #[builtin] format!("Hello", fill = '0', width = 10);
/// let string = format!("{value:?}");
/// assert!(string is String);
/// ```
#[rune::function(keep, instance, protocol = STRING_DEBUG)]
fn format_string_debug(format: &Format, f: &mut Formatter) -> VmResult<()> {
VmResult::Ok(vm_try!(vm_write!(f, "{format:?}")))
}

/// Clones a format specification.
///
/// # Examples
///
/// ```rune
/// let value = #[builtin] format!("Hello", fill = '0', width = 10);
/// let vlaue2 = value.clone();
/// assert_eq!(format!("{value}"), "Hello00000");
/// ```
#[rune::function(keep, instance, protocol = CLONE)]
fn format_clone(this: &Format) -> VmResult<Format> {
VmResult::Ok(vm_try!(this.try_clone()))
}
18 changes: 9 additions & 9 deletions crates/rune/src/modules/future.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use crate as rune;
use crate::alloc::Vec;
use crate::runtime::{
Future, Inline, Mut, Mutable, SelectFuture, Value, ValueBorrowRef, ValueRef, VmErrorKind,
BorrowRefRepr, Future, Inline, Mut, Mutable, RefRepr, SelectFuture, Value, VmErrorKind,
VmResult,
};
use crate::{ContextError, Module};
Expand All @@ -28,15 +28,15 @@ where
let mut results = vm_try!(Vec::try_with_capacity(len));

for (index, value) in values.into_iter().enumerate() {
let value = match vm_try!(value.value_ref()) {
ValueRef::Inline(value) => {
let value = match vm_try!(value.as_ref_repr()) {
RefRepr::Inline(value) => {
return VmResult::err([
VmErrorKind::expected::<Future>(value.type_info()),
VmErrorKind::bad_argument(index),
]);
}
ValueRef::Mutable(value) => vm_try!(value.clone().into_mut()),
ValueRef::Any(value) => {
RefRepr::Mutable(value) => vm_try!(value.clone().into_mut()),
RefRepr::Any(value) => {
return VmResult::err([
VmErrorKind::expected::<Future>(value.type_info()),
VmErrorKind::bad_argument(index),
Expand Down Expand Up @@ -101,15 +101,15 @@ where
/// ```
#[rune::function]
async fn join(value: Value) -> VmResult<Value> {
match vm_try!(value.borrow_ref()) {
ValueBorrowRef::Inline(value) => match value {
match vm_try!(value.borrow_ref_repr()) {
BorrowRefRepr::Inline(value) => match value {
Inline::Unit => VmResult::Ok(Value::unit()),
value => VmResult::err([
VmErrorKind::bad_argument(0),
VmErrorKind::expected::<crate::runtime::Vec>(value.type_info()),
]),
},
ValueBorrowRef::Mutable(value) => match *value {
BorrowRefRepr::Mutable(value) => match *value {
Mutable::Tuple(ref tuple) => VmResult::Ok(vm_try!(
try_join_impl(tuple.iter(), tuple.len(), |vec| VmResult::Ok(vm_try!(
Value::tuple(vec)
Expand All @@ -124,7 +124,7 @@ async fn join(value: Value) -> VmResult<Value> {
VmErrorKind::expected::<crate::runtime::Vec>(value.type_info()),
]),
},
ValueBorrowRef::Any(value) => VmResult::err([
BorrowRefRepr::Any(value) => VmResult::err([
VmErrorKind::bad_argument(0),
VmErrorKind::expected::<crate::runtime::Vec>(value.type_info()),
]),
Expand Down
14 changes: 7 additions & 7 deletions crates/rune/src/modules/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use crate::modules::collections::VecDeque;
use crate::modules::collections::{HashMap, HashSet};
use crate::runtime::range::RangeIter;
use crate::runtime::{
FromValue, Function, Inline, InstAddress, Object, Output, OwnedTuple, Protocol, TypeHash,
Value, ValueBorrowRef, Vec, VmErrorKind, VmResult,
BorrowRefRepr, FromValue, Function, Inline, InstAddress, Object, Output, OwnedTuple, Protocol,
TypeHash, Value, Vec, VmErrorKind, VmResult,
};
use crate::shared::Caller;
use crate::{Any, ContextError, Module, Params};
Expand Down Expand Up @@ -485,17 +485,17 @@ pub fn module() -> Result<Module, ContextError> {
let mut string = String::new();

while let Some(value) = vm_try!(next.call((&iter,))) {
match vm_try!(value.borrow_ref()) {
ValueBorrowRef::Inline(Inline::Char(c)) => {
match vm_try!(value.borrow_ref_repr()) {
BorrowRefRepr::Inline(Inline::Char(c)) => {
vm_try!(string.try_push(*c));
}
ValueBorrowRef::Inline(value) => {
BorrowRefRepr::Inline(value) => {
return VmResult::expected::<String>(value.type_info());
}
ValueBorrowRef::Mutable(value) => {
BorrowRefRepr::Mutable(value) => {
return VmResult::expected::<String>(value.type_info());
}
ValueBorrowRef::Any(value) => match value.type_hash() {
BorrowRefRepr::Any(value) => match value.type_hash() {
String::HASH => {
let s = vm_try!(value.borrow_ref::<String>());
vm_try!(string.try_push_str(&s));
Expand Down
Loading

0 comments on commit fc7ee77

Please sign in to comment.