1
0

Expand VM functionality; Slow the VM down quite a bit

This commit is contained in:
Jeff 2025-02-17 02:37:21 -05:00
parent 7153cc16f2
commit b0f7ca7992
8 changed files with 362 additions and 132 deletions

View File

@ -299,7 +299,7 @@ impl<'src> Compiler<'src> {
.iter()
.rev()
.find_map(|(instruction, r#type, _)| {
if (r#type == &Type::Byte)
if *r#type == Type::Byte
|| (instruction.operation() == Operation::LOAD_ENCODED
&& instruction.b_type() == TypeCode::BYTE)
{
@ -332,8 +332,11 @@ impl<'src> Compiler<'src> {
self.instructions
.iter()
.rev()
.find_map(|(instruction, _, _)| {
if instruction.b_type() == TypeCode::FLOAT && instruction.yields_value() {
.find_map(|(instruction, r#type, _)| {
if *r#type == Type::Float
|| (instruction.operation() == Operation::LOAD_CONSTANT
&& instruction.b_type() == TypeCode::FLOAT)
{
Some(instruction.a_field() + 1)
} else {
None

View File

@ -14,9 +14,9 @@ pub fn add_bytes(_: &mut usize, instruction: &InstructionFields, thread: &mut Th
let right_index = instruction.c_field as usize;
let current_frame = thread.current_frame_mut();
let left_value = current_frame.get_byte_from_register(left_index);
let right_value = current_frame.get_byte_from_register(right_index);
let sum = left_value.add(right_value);
let left_value = current_frame.get_byte_from_register(left_index).clone();
let right_value = current_frame.get_byte_from_register(right_index).clone();
let sum = left_value.add(&right_value);
current_frame
.registers
@ -72,13 +72,15 @@ pub fn add_floats(_: &mut usize, instruction: &InstructionFields, thread: &mut T
current_frame.get_float_constant(left)
} else {
current_frame.get_float_from_register(left)
};
}
.clone();
let right_value = if right_is_constant {
current_frame.get_float_constant(right)
} else {
current_frame.get_float_from_register(right)
};
let sum = left_value.add(right_value);
}
.clone();
let sum = left_value.add(&right_value);
current_frame
.registers
@ -100,13 +102,15 @@ pub fn add_integers(_: &mut usize, instruction: &InstructionFields, thread: &mut
current_frame.get_integer_constant(left)
} else {
current_frame.get_integer_from_register(left)
};
}
.clone();
let right_value = if right_is_constant {
current_frame.get_integer_constant(right)
} else {
current_frame.get_integer_from_register(right)
};
let sum = left_value.add(right_value);
}
.clone();
let sum = left_value.add(&right_value);
current_frame
.registers
@ -201,12 +205,13 @@ pub fn add_string_character(_: &mut usize, instruction: &InstructionFields, thre
}
pub fn optimized_add_integer(
_: &mut usize,
instruction: &InstructionFields,
thread: &mut Thread,
cache: &mut Option<[RuntimeValue<i64>; 3]>,
) {
if let Some([destination, left, right]) = cache {
trace!("ADD_INTEGERS_OPTIMIZED using cache");
trace!("OPTIMIZED_ADD using integer cache");
let sum = left.add(right);

View File

@ -139,9 +139,9 @@ pub fn optimized_equal_integers(
ip: &mut usize,
instruction: &InstructionFields,
thread: &mut Thread,
cache: &mut Option<[RuntimeValue<i64>; 2]>,
cache: &mut Option<[RuntimeValue<i64>; 3]>,
) {
if let Some([left, right]) = cache {
if let Some([_, left, right]) = cache {
trace!("equal_INTEGERS_OPTIMIZED using cache");
let is_equal = left == right;
@ -193,6 +193,6 @@ pub fn optimized_equal_integers(
*ip += 1;
}
*cache = Some([left_value, right_value]);
*cache = Some([RuntimeValue::Raw(0), left_value, right_value]);
}
}

View File

@ -139,10 +139,10 @@ pub fn optimized_less_integers(
ip: &mut usize,
instruction: &InstructionFields,
thread: &mut Thread,
cache: &mut Option<[RuntimeValue<i64>; 2]>,
cache: &mut Option<[RuntimeValue<i64>; 3]>,
) {
if let Some([left, right]) = cache {
trace!("LESS_INTEGERS_OPTIMIZED using cache");
if let Some([_, left, right]) = cache {
trace!("OPTIMIZED_LESS using integer cache");
let is_less_than = left < right;
@ -193,6 +193,6 @@ pub fn optimized_less_integers(
*ip += 1;
}
*cache = Some([left_value, right_value]);
*cache = Some([RuntimeValue::Raw(0), left_value, right_value]);
}
}

View File

@ -139,9 +139,9 @@ pub fn optimized_less_equal_integers(
ip: &mut usize,
instruction: &InstructionFields,
thread: &mut Thread,
cache: &mut Option<[RuntimeValue<i64>; 2]>,
cache: &mut Option<[RuntimeValue<i64>; 3]>,
) {
if let Some([left, right]) = cache {
if let Some([_, left, right]) = cache {
trace!("LESS_INTEGERS_OPTIMIZED using cache");
let is_less_than_or_equal = left <= right;
@ -193,6 +193,6 @@ pub fn optimized_less_equal_integers(
*ip += 1;
}
*cache = Some([left_value, right_value]);
*cache = Some([RuntimeValue::Raw(0), left_value, right_value]);
}
}

View File

@ -25,14 +25,18 @@ use std::fmt::{self, Display, Formatter};
use crate::{
instruction::{InstructionFields, TypeCode},
Operation, Value,
AbstractList, ConcreteValue, Operation, Value,
};
use super::{call_frame::RuntimeValue, thread::Thread};
use super::{call_frame::RuntimeValue, thread::Thread, Pointer};
pub type ActionLogic = fn(&mut usize, &InstructionFields, &mut Thread);
pub type OptimizedActionLogicIntegers =
fn(&mut usize, &InstructionFields, &mut Thread, &mut Option<[RuntimeValue<i64>; 3]>);
#[derive(Debug)]
pub struct ActionSequence {
actions: Vec<(Action, InstructionFields)>,
actions: Vec<Action>,
}
impl ActionSequence {
@ -49,13 +53,13 @@ impl ActionSequence {
let mut loop_actions = Vec::with_capacity(backward_offset + 1);
let jump_action = Action::optimized(&instruction);
loop_actions.push((jump_action, instruction));
loop_actions.push(jump_action);
for _ in 0..backward_offset {
let instruction = instructions_reversed.next().unwrap();
let action = Action::optimized(&instruction);
loop_actions.push((action, instruction));
loop_actions.push(action);
}
loop_actions.reverse();
@ -64,7 +68,7 @@ impl ActionSequence {
actions: loop_actions,
});
actions.push((r#loop, instruction));
actions.push(r#loop);
continue;
}
@ -72,7 +76,7 @@ impl ActionSequence {
let action = Action::unoptimized(instruction);
actions.push((action, instruction));
actions.push(action);
}
actions.reverse();
@ -84,7 +88,11 @@ impl ActionSequence {
let mut local_ip = 0;
while local_ip < self.actions.len() {
let (action, instruction) = &mut self.actions[local_ip];
let action = if cfg!(debug_assertions) {
self.actions.get_mut(local_ip).unwrap()
} else {
unsafe { self.actions.get_unchecked_mut(local_ip) }
};
local_ip += 1;
info!("Run {action}");
@ -96,17 +104,12 @@ impl ActionSequence {
Action::Loop { actions } => {
actions.run(thread);
}
Action::OptimizedAddIntegers(cache) => {
optimized_add_integer(instruction, thread, cache);
}
Action::OptimizedEqualIntegers(cache) => {
optimized_equal_integers(&mut local_ip, instruction, thread, cache);
}
Action::OptimizedLessIntegers(cache) => {
optimized_less_integers(&mut local_ip, instruction, thread, cache);
}
Action::OptimizedLessEqualIntegers(cache) => {
optimized_less_equal_integers(&mut local_ip, instruction, thread, cache);
Action::OptimizedIntegers {
logic,
instruction,
cache,
} => {
logic(&mut local_ip, &*instruction, thread, cache);
}
Action::OptimizedJumpForward { offset } => {
local_ip += *offset;
@ -123,7 +126,7 @@ impl Display for ActionSequence {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "[")?;
for (index, (action, _)) in self.actions.iter().enumerate() {
for (index, action) in self.actions.iter().enumerate() {
if index > 0 {
write!(f, ", ")?;
}
@ -144,10 +147,11 @@ enum Action {
Loop {
actions: ActionSequence,
},
OptimizedAddIntegers(Option<[RuntimeValue<i64>; 3]>),
OptimizedEqualIntegers(Option<[RuntimeValue<i64>; 2]>),
OptimizedLessIntegers(Option<[RuntimeValue<i64>; 2]>),
OptimizedLessEqualIntegers(Option<[RuntimeValue<i64>; 2]>),
OptimizedIntegers {
logic: OptimizedActionLogicIntegers,
instruction: InstructionFields,
cache: Option<[RuntimeValue<i64>; 3]>,
},
OptimizedJumpForward {
offset: usize,
},
@ -224,19 +228,35 @@ impl Action {
pub fn optimized(instruction: &InstructionFields) -> Self {
match instruction.operation {
Operation::ADD => match (instruction.b_type, instruction.c_type) {
(TypeCode::INTEGER, TypeCode::INTEGER) => Action::OptimizedAddIntegers(None),
(TypeCode::INTEGER, TypeCode::INTEGER) => Action::OptimizedIntegers {
logic: optimized_add_integer,
instruction: *instruction,
cache: None,
},
_ => todo!(),
},
Operation::EQUAL => match (instruction.b_type, instruction.c_type) {
(TypeCode::INTEGER, TypeCode::INTEGER) => Action::OptimizedEqualIntegers(None),
(TypeCode::INTEGER, TypeCode::INTEGER) => Action::OptimizedIntegers {
logic: optimized_equal_integers,
instruction: *instruction,
cache: None,
},
_ => todo!(),
},
Operation::LESS => match (instruction.b_type, instruction.c_type) {
(TypeCode::INTEGER, TypeCode::INTEGER) => Action::OptimizedLessIntegers(None),
(TypeCode::INTEGER, TypeCode::INTEGER) => Action::OptimizedIntegers {
logic: optimized_less_integers,
instruction: *instruction,
cache: None,
},
_ => todo!(),
},
Operation::LESS_EQUAL => match (instruction.b_type, instruction.c_type) {
(TypeCode::INTEGER, TypeCode::INTEGER) => Action::OptimizedLessEqualIntegers(None),
(TypeCode::INTEGER, TypeCode::INTEGER) => Action::OptimizedIntegers {
logic: optimized_less_equal_integers,
instruction: *instruction,
cache: None,
},
_ => todo!(),
},
Operation::JUMP => {
@ -267,17 +287,8 @@ impl Display for Action {
Action::Loop { actions } => {
write!(f, "LOOP: {actions}")
}
Action::OptimizedAddIntegers { .. } => {
write!(f, "ADD_INTEGERS_OPTIMIZED")
}
Action::OptimizedEqualIntegers { .. } => {
write!(f, "EQUAL_INTEGERS_OPTIMIZED")
}
Action::OptimizedLessIntegers { .. } => {
write!(f, "LESS_INTEGERS_OPTIMIZED")
}
Action::OptimizedLessEqualIntegers { .. } => {
write!(f, "LESS_EQUAL_INTEGERS_OPTIMIZED")
Action::OptimizedIntegers { instruction, .. } => {
write!(f, "OPTIMIZED_{}", instruction.operation)
}
Action::OptimizedJumpForward { offset } => {
write!(f, "JUMP +{offset}")
@ -289,8 +300,6 @@ impl Display for Action {
}
}
pub type ActionLogic = fn(&mut usize, &InstructionFields, &mut Thread);
fn point(_: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
todo!()
}
@ -388,7 +397,96 @@ fn load_constant(ip: &mut usize, instruction: &InstructionFields, thread: &mut T
}
fn load_list(ip: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
todo!()
let destination = instruction.a_field as usize;
let start_register = instruction.b_field as usize;
let item_type = instruction.b_type;
let end_register = instruction.c_field as usize;
let jump_next = instruction.d_field;
let current_frame = thread.current_frame_mut();
let mut item_pointers = Vec::with_capacity(end_register - start_register + 1);
match item_type {
TypeCode::BOOLEAN => {
for register_index in start_register..=end_register {
let register_is_closed = current_frame.registers.booleans.is_closed(register_index);
if register_is_closed {
continue;
}
item_pointers.push(Pointer::Register(register_index));
}
}
TypeCode::BYTE => {
for register_index in start_register..=end_register {
let register_is_closed = current_frame.registers.bytes.is_closed(register_index);
if register_is_closed {
continue;
}
item_pointers.push(Pointer::Register(register_index));
}
}
TypeCode::CHARACTER => {
for register_index in start_register..=end_register {
let register_is_closed =
current_frame.registers.characters.is_closed(register_index);
if register_is_closed {
continue;
}
item_pointers.push(Pointer::Register(register_index));
}
}
TypeCode::FLOAT => {
for register_index in start_register..=end_register {
let register_is_closed = current_frame.registers.floats.is_closed(register_index);
if register_is_closed {
continue;
}
item_pointers.push(Pointer::Register(register_index));
}
}
TypeCode::INTEGER => {
for register_index in start_register..=end_register {
let register_is_closed = current_frame.registers.integers.is_closed(register_index);
if register_is_closed {
continue;
}
item_pointers.push(Pointer::Register(register_index));
}
}
TypeCode::STRING => {
for register_index in start_register..=end_register {
let register_is_closed = current_frame.registers.strings.is_closed(register_index);
if register_is_closed {
continue;
}
item_pointers.push(Pointer::Register(register_index));
}
}
_ => unreachable!(),
}
let list = RuntimeValue::Raw(AbstractList {
item_type,
item_pointers,
});
current_frame.registers.lists.get_mut(destination).set(list);
if jump_next {
*ip += 1;
}
}
fn load_function(_: &mut usize, _: &InstructionFields, _: &mut Thread) {
@ -423,10 +521,6 @@ fn test_set(_: &mut usize, _: &InstructionFields, _: &mut Thread) {
todo!()
}
fn less_equal(ip: &mut usize, instruction: &InstructionFields, thread: &mut Thread) {
todo!()
}
fn negate(_: &mut usize, _: &InstructionFields, _: &mut Thread) {
todo!()
}
@ -488,7 +582,76 @@ fn r#return(_: &mut usize, instruction: &InstructionFields, thread: &mut Thread)
thread.return_value = Some(Value::string(return_value));
}
TypeCode::LIST => {
todo!()
let abstract_list = current_frame
.get_list_from_register(return_register)
.clone_inner();
let mut concrete_list = Vec::with_capacity(abstract_list.item_pointers.len());
match abstract_list.item_type {
TypeCode::BOOLEAN => {
for pointer in abstract_list.item_pointers {
let boolean = current_frame
.get_boolean_from_pointer(&pointer)
.clone_inner();
let value = ConcreteValue::Boolean(boolean);
concrete_list.push(value);
}
}
TypeCode::BYTE => {
for pointer in abstract_list.item_pointers {
let byte = current_frame.get_byte_from_pointer(&pointer).clone_inner();
let value = ConcreteValue::Byte(byte);
concrete_list.push(value);
}
}
TypeCode::CHARACTER => {
for pointer in abstract_list.item_pointers {
let character = current_frame
.get_character_from_pointer(&pointer)
.clone_inner();
let value = ConcreteValue::Character(character);
concrete_list.push(value);
}
}
TypeCode::FLOAT => {
for pointer in abstract_list.item_pointers {
let float =
current_frame.get_float_from_pointer(&pointer).clone_inner();
let value = ConcreteValue::Float(float);
concrete_list.push(value);
}
}
TypeCode::INTEGER => {
for pointer in abstract_list.item_pointers {
let integer = current_frame
.get_integer_from_pointer(&pointer)
.clone_inner();
let value = ConcreteValue::Integer(integer);
concrete_list.push(value);
}
}
TypeCode::STRING => {
for pointer in abstract_list.item_pointers {
let string = current_frame
.get_string_from_pointer(&pointer)
.clone_inner();
let value = ConcreteValue::String(string);
concrete_list.push(value);
}
}
_ => todo!(),
}
thread.return_value = Some(Value::Concrete(ConcreteValue::list(
concrete_list,
abstract_list.item_type,
)));
}
_ => unreachable!(),
}

View File

@ -231,6 +231,62 @@ impl CallFrame {
unsafe { self.constants.strings.get_unchecked_mut(constant_index) }
}
}
pub fn get_list_from_register(&self, register_index: usize) -> &RuntimeValue<AbstractList> {
let register = self.registers.lists.get(register_index);
match register {
Register::Value { value, .. } => value,
Register::Pointer { pointer, .. } => self.get_list_from_pointer(pointer),
}
}
pub fn get_list_from_register_mut(
&mut self,
register_index: usize,
) -> &mut RuntimeValue<AbstractList> {
let register = self.registers.lists.get_mut(register_index);
match register {
Register::Value { value, .. } => value,
Register::Pointer { .. } => panic!("Attempted to get mutable list from pointer"),
}
}
pub fn get_list_from_pointer(&self, pointer: &Pointer) -> &RuntimeValue<AbstractList> {
match pointer {
Pointer::Register(register_index) => self.get_list_from_register(*register_index),
Pointer::Constant(_) => panic!("Attempted to get list from constant pointer"),
}
}
pub fn get_function_from_register(&self, register_index: usize) -> &RuntimeValue<Function> {
let register = self.registers.functions.get(register_index);
match register {
Register::Value { value, .. } => value,
Register::Pointer { pointer, .. } => self.get_function_from_pointer(pointer),
}
}
pub fn get_function_from_register_mut(
&mut self,
register_index: usize,
) -> &mut RuntimeValue<Function> {
let register = self.registers.functions.get_mut(register_index);
match register {
Register::Value { value, .. } => value,
Register::Pointer { .. } => panic!("Attempted to get mutable function from pointer"),
}
}
pub fn get_function_from_pointer(&self, pointer: &Pointer) -> &RuntimeValue<Function> {
match pointer {
Pointer::Register(register_index) => self.get_function_from_register(*register_index),
Pointer::Constant(_) => panic!("Attempted to get function from constant pointer"),
}
}
}
impl Display for CallFrame {
@ -460,42 +516,66 @@ impl<T: Clone> RuntimeValue<T> {
}
}
impl<T: Add<Output = T> + Copy> Add for &RuntimeValue<T> {
type Output = T;
const BYTE_ADD: fn(u8, u8) -> u8 = u8::saturating_add;
impl Add for &RuntimeValue<u8> {
type Output = u8;
fn add(self, other: Self) -> Self::Output {
match (self, other) {
(RuntimeValue::Raw(left), RuntimeValue::Raw(right)) => *left + *right,
(RuntimeValue::Raw(left), RuntimeValue::Rc(right)) => *left + **right,
(RuntimeValue::Raw(left), RuntimeValue::RefCell(right)) => {
let right = right.borrow();
let left = match self {
RuntimeValue::Raw(value) => *value,
RuntimeValue::Rc(value) => **value,
RuntimeValue::RefCell(value) => *value.borrow(),
};
let right = match other {
RuntimeValue::Raw(value) => *value,
RuntimeValue::Rc(value) => **value,
RuntimeValue::RefCell(value) => *value.borrow(),
};
*left + *right
}
(RuntimeValue::Rc(left), RuntimeValue::Raw(right)) => **left + *right,
(RuntimeValue::Rc(left), RuntimeValue::Rc(right)) => **left + **right,
(RuntimeValue::Rc(left), RuntimeValue::RefCell(right)) => {
let right = right.borrow();
BYTE_ADD(left, right)
}
}
**left + *right
}
(RuntimeValue::RefCell(left), RuntimeValue::RefCell(right)) => {
let left = left.borrow();
let right = right.borrow();
const FLOAT_ADD: fn(f64, f64) -> f64 = f64::add;
*left + *right
}
(RuntimeValue::RefCell(left), RuntimeValue::Raw(right)) => {
let left = left.borrow();
impl Add for &RuntimeValue<f64> {
type Output = f64;
*left + *right
}
(RuntimeValue::RefCell(left), RuntimeValue::Rc(right)) => {
let left = left.borrow();
fn add(self, other: Self) -> Self::Output {
let left = match self {
RuntimeValue::Raw(value) => *value,
RuntimeValue::Rc(value) => **value,
RuntimeValue::RefCell(value) => *value.borrow(),
};
let right = match other {
RuntimeValue::Raw(value) => *value,
RuntimeValue::Rc(value) => **value,
RuntimeValue::RefCell(value) => *value.borrow(),
};
*left + **right
}
}
FLOAT_ADD(left, right)
}
}
const INTEGER_ADD: fn(i64, i64) -> i64 = i64::saturating_add;
impl Add for &RuntimeValue<i64> {
type Output = i64;
fn add(self, other: Self) -> Self::Output {
let left = match self {
RuntimeValue::Raw(value) => *value,
RuntimeValue::Rc(value) => **value,
RuntimeValue::RefCell(value) => *value.borrow(),
};
let right = match other {
RuntimeValue::Raw(value) => *value,
RuntimeValue::Rc(value) => **value,
RuntimeValue::RefCell(value) => *value.borrow(),
};
INTEGER_ADD(left, right)
}
}

View File

@ -1,6 +1,6 @@
use dust_lang::{
Chunk, ConcreteValue, DustString, FunctionType, Instruction, Span, Type, Value, compile,
instruction::TypeCode, run,
compile, instruction::TypeCode, run, Chunk, ConcreteValue, DustString, FunctionType,
Instruction, Span, Type, Value,
};
#[test]
@ -67,7 +67,7 @@ fn load_character() {
Instruction::r#return(true, 0, TypeCode::CHARACTER),
],
positions: vec![Span(0, 3), Span(3, 3)],
constants: vec![ConcreteValue::Character('a')],
character_constants: vec!['a'],
..Chunk::default()
};
let return_value = Some(Value::character('a'));
@ -86,7 +86,7 @@ fn load_float() {
Instruction::r#return(true, 0, TypeCode::FLOAT),
],
positions: vec![Span(0, 5), Span(5, 5)],
constants: vec![ConcreteValue::Float(42.42)],
float_constants: vec![42.42],
..Chunk::default()
};
let return_value = Some(Value::float(42.42));
@ -105,7 +105,7 @@ fn load_integer() {
Instruction::r#return(true, 0, TypeCode::INTEGER),
],
positions: vec![Span(0, 2), Span(2, 2)],
constants: vec![ConcreteValue::Integer(42)],
integer_constants: vec![42],
..Chunk::default()
};
let return_value = Some(Value::integer(42));
@ -124,7 +124,7 @@ fn load_string() {
Instruction::r#return(true, 0, TypeCode::STRING),
],
positions: vec![Span(0, 15), Span(15, 15)],
constants: vec![ConcreteValue::String(DustString::from("Hello, World!"))],
string_constants: vec![DustString::from("Hello, World!")],
..Chunk::default()
};
let return_value = Some(Value::string("Hello, World!"));
@ -191,7 +191,7 @@ fn load_character_list() {
Instruction::r#return(true, 0, TypeCode::LIST),
],
positions: vec![Span(1, 4), Span(6, 9), Span(0, 10), Span(10, 10)],
constants: vec![ConcreteValue::Character('a'), ConcreteValue::Character('b')],
character_constants: vec!['a', 'b'],
..Chunk::default()
};
let return_value = Some(Value::Concrete(ConcreteValue::List {
@ -215,7 +215,7 @@ fn load_float_list() {
Instruction::r#return(true, 0, TypeCode::LIST),
],
positions: vec![Span(1, 6), Span(8, 13), Span(0, 14), Span(14, 14)],
constants: vec![ConcreteValue::Float(42.42), ConcreteValue::Float(24.24)],
float_constants: vec![42.42, 24.24],
..Chunk::default()
};
let return_value = Some(Value::Concrete(ConcreteValue::List {
@ -240,11 +240,7 @@ fn load_integer_list() {
Instruction::r#return(true, 0, TypeCode::LIST),
],
positions: vec![Span(1, 2), Span(4, 5), Span(7, 8), Span(0, 9), Span(9, 9)],
constants: vec![
ConcreteValue::Integer(1),
ConcreteValue::Integer(2),
ConcreteValue::Integer(3),
],
integer_constants: vec![1, 2, 3],
..Chunk::default()
};
let return_value = Some(Value::Concrete(ConcreteValue::List {
@ -272,10 +268,7 @@ fn load_string_list() {
Instruction::r#return(true, 0, TypeCode::LIST),
],
positions: vec![Span(1, 8), Span(10, 17), Span(0, 18), Span(18, 18)],
constants: vec![
ConcreteValue::String(DustString::from("Hello")),
ConcreteValue::String(DustString::from("World")),
],
string_constants: vec![DustString::from("Hello"), DustString::from("World")],
..Chunk::default()
};
let return_value = Some(Value::Concrete(ConcreteValue::List {
@ -315,12 +308,7 @@ fn load_nested_list() {
Span(0, 16),
Span(16, 16),
],
constants: vec![
ConcreteValue::Integer(1),
ConcreteValue::Integer(2),
ConcreteValue::Integer(3),
ConcreteValue::Integer(4),
],
integer_constants: vec![1, 2, 3, 4],
..Chunk::default()
};
let return_value = Some(Value::Concrete(ConcreteValue::List {
@ -386,16 +374,7 @@ fn load_deeply_nested_list() {
Span(0, 36),
Span(36, 36),
],
constants: vec![
ConcreteValue::Integer(1),
ConcreteValue::Integer(2),
ConcreteValue::Integer(3),
ConcreteValue::Integer(4),
ConcreteValue::Integer(5),
ConcreteValue::Integer(6),
ConcreteValue::Integer(7),
ConcreteValue::Integer(8),
],
integer_constants: vec![1, 2, 3, 4, 5, 6, 7, 8],
..Chunk::default()
};
let return_value = Some(Value::Concrete(ConcreteValue::List {