Skip to content

Commit

Permalink
rune: Simplify the empty sentinel value (#881)
Browse files Browse the repository at this point in the history
  • Loading branch information
udoprog authored Nov 5, 2024
1 parent d2dd714 commit 02e6344
Show file tree
Hide file tree
Showing 35 changed files with 684 additions and 684 deletions.
30 changes: 24 additions & 6 deletions crates/rune/src/cli/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,8 @@ pub(super) async fn run(

let mut functions = unit.iter_functions().peekable();
let mut strings = unit.iter_static_strings().peekable();
let mut bytes = unit.iter_static_bytes().peekable();
let mut drop_sets = unit.iter_static_drop_sets().peekable();
let mut keys = unit.iter_static_object_keys().peekable();
let mut constants = unit.iter_constants().peekable();

Expand All @@ -199,16 +201,16 @@ pub(super) async fn run(
if strings.peek().is_some() {
writeln!(io.stdout, "# strings")?;

for string in strings {
writeln!(io.stdout, "{} = {:?}", string.hash(), string)?;
for (i, string) in strings.enumerate() {
writeln!(io.stdout, "{i} = {string:?}")?;
}
}

if args.dump_constants && constants.peek().is_some() {
writeln!(io.stdout, "# constants")?;
if bytes.peek().is_some() {
writeln!(io.stdout, "# bytes")?;

for constant in constants {
writeln!(io.stdout, "{} = {:?}", constant.0, constant.1)?;
for (i, bytes) in bytes.enumerate() {
writeln!(io.stdout, "{i} = {bytes:?}")?;
}
}

Expand All @@ -219,6 +221,22 @@ pub(super) async fn run(
writeln!(io.stdout, "{} = {:?}", hash, keys)?;
}
}

if drop_sets.peek().is_some() {
writeln!(io.stdout, "# drop sets")?;

for (i, set) in drop_sets.enumerate() {
writeln!(io.stdout, "{i} = {set:?}")?;
}
}

if args.dump_constants && constants.peek().is_some() {
writeln!(io.stdout, "# constants")?;

for (hash, constant) in constants {
writeln!(io.stdout, "{hash} = {constant:?}")?;
}
}
}

let runtime = Arc::new(context.runtime()?);
Expand Down
6 changes: 3 additions & 3 deletions crates/rune/src/cli/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use crate::cli::{
use crate::compile::FileSourceLoader;
use crate::doc::{TestKind, TestParams};
use crate::modules::capture_io::CaptureIo;
use crate::runtime::{ReprRef, Value, Vm, VmError, VmResult};
use crate::runtime::{Repr, Value, Vm, VmError, VmResult};
use crate::{Diagnostics, Hash, Item, ItemBuf, Source, Sources, TypeHash, Unit};

mod cli {
Expand Down Expand Up @@ -534,8 +534,8 @@ impl TestCase {
capture_io.drain_into(&mut self.output)?;

self.outcome = match result {
VmResult::Ok(v) => match v.as_ref()? {
ReprRef::Any(value) => match value.type_hash() {
VmResult::Ok(v) => match v.as_ref() {
Repr::Any(value) => match value.type_hash() {
Result::<Value, Value>::HASH => {
let result = value.borrow_ref::<Result<Value, Value>>()?;

Expand Down
4 changes: 2 additions & 2 deletions crates/rune/src/compile/ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -534,8 +534,8 @@ impl IrAssignOp {
where
S: Copy + Spanned,
{
if let Some(Inline::Signed(target)) = target.as_inline_mut().with_span(spanned)? {
if let Some(Inline::Signed(operand)) = operand.as_inline().with_span(spanned)? {
if let Some(Inline::Signed(target)) = target.as_inline_mut() {
if let Some(Inline::Signed(operand)) = operand.as_inline() {
return self.assign_int(spanned, target, *operand);
}
}
Expand Down
53 changes: 21 additions & 32 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, ReprRef, Value};
use crate::runtime::{Inline, Object, OwnedTuple, Repr, 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.as_ref().with_span(ir)?;
let b = b.as_ref().with_span(ir)?;
let a = a.as_ref();
let b = b.as_ref();

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

return Ok(Value::from(out));
}
(ReprRef::Any(a), ReprRef::Any(b)) => {
(Repr::Any(a), Repr::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,34 +353,23 @@ fn eval_ir_template(
}
ir::IrTemplateComponent::Ir(ir) => {
let const_value = eval_ir(ir, interp, used)?;
let value = const_value.as_ref().with_span(ir)?;

match value {
ReprRef::Inline(value) => match value {
Inline::Signed(integer) => {
write!(buf, "{integer}")?;
}
Inline::Float(float) => {
let mut buffer = ryu::Buffer::new();
buf.try_push_str(buffer.format(*float))?;
}
Inline::Bool(b) => {
write!(buf, "{b}")?;
}
_ => {
return Err(EvalOutcome::not_const(ir));
}
},
ReprRef::Any(value) => match value.type_hash() {
String::HASH => {
let s = value.borrow_ref::<String>().with_span(ir)?;
buf.try_push_str(&s)?;
}
_ => {
return Err(EvalOutcome::not_const(ir));
}
},
ReprRef::Dynamic(..) => {
match const_value.as_ref() {
Repr::Inline(Inline::Signed(integer)) => {
write!(buf, "{integer}")?;
}
Repr::Inline(Inline::Float(float)) => {
let mut buffer = ryu::Buffer::new();
buf.try_push_str(buffer.format(*float))?;
}
Repr::Inline(Inline::Bool(b)) => {
write!(buf, "{b}")?;
}
Repr::Any(value) if value.type_hash() == String::HASH => {
let s = value.borrow_ref::<String>().with_span(ir)?;
buf.try_push_str(&s)?;
}
_ => {
return Err(EvalOutcome::not_const(ir));
}
}
Expand Down
65 changes: 25 additions & 40 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::{self, ConstValue, Object, OwnedTuple, ReprRef, Value};
use crate::runtime::{self, ConstValue, Object, OwnedTuple, Repr, Value};
use crate::TypeHash;

/// The interpreter that executed [Ir][crate::ir::Ir].
Expand Down Expand Up @@ -200,45 +200,30 @@ impl ir::Scopes {
}
ir::IrTargetKind::Index(target, index) => {
let value = self.get_target(target)?;
let target = value.as_ref().with_span(ir_target)?;

match target {
ReprRef::Inline(value) => {
return Err(compile::Error::expected_type::<OwnedTuple>(
ir_target,
value.type_info(),
));
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());
}
}
ReprRef::Dynamic(value) => {
runtime::OwnedTuple::HASH => {
let tuple = value
.borrow_ref::<runtime::OwnedTuple>()
.with_span(ir_target)?;

if let Some(value) = tuple.get(*index) {
return Ok(value.clone());
}
}
_ => {
return Err(compile::Error::expected_type::<OwnedTuple>(
ir_target,
value.type_info(),
));
}
ReprRef::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());
}
}
runtime::OwnedTuple::HASH => {
let tuple = value
.borrow_ref::<runtime::OwnedTuple>()
.with_span(ir_target)?;

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

Err(compile::Error::new(
Expand Down Expand Up @@ -270,20 +255,20 @@ impl ir::Scopes {
ir::IrTargetKind::Index(target, index) => {
let target = self.get_target(target)?;

match target.as_ref().with_span(ir_target)? {
ReprRef::Inline(value) => {
match target.as_ref() {
Repr::Inline(value) => {
return Err(compile::Error::expected_type::<OwnedTuple>(
ir_target,
value.type_info(),
));
}
ReprRef::Dynamic(value) => {
Repr::Dynamic(value) => {
return Err(compile::Error::expected_type::<OwnedTuple>(
ir_target,
value.type_info(),
));
}
ReprRef::Any(any) => match any.type_hash() {
Repr::Any(any) => match any.type_hash() {
runtime::Vec::HASH => {
let mut vec = any.borrow_mut::<runtime::Vec>().with_span(ir_target)?;

Expand Down Expand Up @@ -345,12 +330,12 @@ impl ir::Scopes {
ir::IrTargetKind::Index(target, index) => {
let current = self.get_target(target)?;

match current.as_ref().with_span(ir_target)? {
ReprRef::Dynamic(value) => Err(compile::Error::expected_type::<OwnedTuple>(
match current.as_ref() {
Repr::Dynamic(value) => Err(compile::Error::expected_type::<OwnedTuple>(
ir_target,
value.type_info(),
)),
ReprRef::Any(value) => match value.type_hash() {
Repr::Any(value) => match value.type_hash() {
runtime::Vec::HASH => {
let mut vec =
value.borrow_mut::<runtime::Vec>().with_span(ir_target)?;
Expand Down
50 changes: 48 additions & 2 deletions crates/rune/src/compile/unit_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ use crate::query::QueryInner;
use crate::runtime::debug::{DebugArgs, DebugSignature};
use crate::runtime::unit::UnitEncoder;
use crate::runtime::{
Call, ConstValue, DebugInfo, DebugInst, Inst, Label, Protocol, Rtti, RttiKind, StaticString,
Unit, UnitFn,
Call, ConstValue, DebugInfo, DebugInst, Inst, InstAddress, Label, Protocol, Rtti, RttiKind,
StaticString, Unit, UnitFn,
};
use crate::{Context, Diagnostics, Hash, Item, SourceId};

Expand Down Expand Up @@ -72,6 +72,10 @@ pub(crate) struct UnitBuilder {
static_object_keys: Vec<Box<[String]>>,
/// Used to detect duplicates in the collection of static object keys.
static_object_keys_rev: HashMap<Hash, usize>,
/// A static string.
drop_sets: Vec<Arc<[InstAddress]>>,
/// Reverse lookup for drop sets.
drop_sets_rev: HashMap<Vec<InstAddress>, usize>,
/// Runtime type information for types.
rtti: hash::Map<Arc<Rtti>>,
/// The current label count.
Expand All @@ -87,6 +91,14 @@ pub(crate) struct UnitBuilder {
}

impl UnitBuilder {
/// Construct a new drop set.
pub(crate) fn drop_set(&mut self) -> DropSet<'_> {
DropSet {
builder: self,
addresses: Vec::new(),
}
}

/// Insert an identifier for debug purposes.
pub(crate) fn insert_debug_ident(&mut self, ident: &str) -> alloc::Result<()> {
self.hash_to_ident
Expand Down Expand Up @@ -150,6 +162,7 @@ impl UnitBuilder {
self.static_strings,
self.static_bytes,
self.static_object_keys,
self.drop_sets,
self.rtti,
self.debug,
self.constants,
Expand Down Expand Up @@ -914,3 +927,36 @@ impl UnitBuilder {
Ok(())
}
}

/// A set of addresses that should be dropped.
pub(crate) struct DropSet<'a> {
builder: &'a mut UnitBuilder,
addresses: Vec<InstAddress>,
}

impl DropSet<'_> {
/// Construct a new drop set.
pub(crate) fn push(&mut self, addr: InstAddress) -> alloc::Result<()> {
self.addresses.try_push(addr)
}

pub(crate) fn finish(self) -> alloc::Result<Option<usize>> {
if self.addresses.is_empty() {
return Ok(None);
}

if let Some(set) = self.builder.drop_sets_rev.get(&self.addresses) {
return Ok(Some(*set));
}

let set = self.builder.drop_sets.len();

self.builder
.drop_sets_rev
.try_insert(self.addresses.try_clone()?, set)?;
self.builder
.drop_sets
.try_push(Arc::from(&self.addresses[..]))?;
Ok(Some(set))
}
}
Loading

0 comments on commit 02e6344

Please sign in to comment.