make the repl app mutable (for expect repl)

This commit is contained in:
Folkert 2022-07-23 13:45:17 +02:00
parent dfbad3c322
commit 6c0217c6f6
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C
5 changed files with 58 additions and 49 deletions

View file

@ -21,27 +21,24 @@ pub fn get_values<'a>(
subs: &'a Subs,
interns: &'a Interns,
start: *const u8,
mut start_offset: usize,
start_offset: usize,
variables: &[Variable],
) -> Result<Vec<Expr<'a>>, ToAstProblem> {
let mut result = Vec::with_capacity(variables.len());
for variable in variables {
let memory = ExpectMemory {
start,
extra_offset: Default::default(),
};
let memory = ExpectMemory { start };
let app = ExpectReplApp {
memory: arena.alloc(memory),
offset: start_offset,
};
let app = arena.alloc(app);
for variable in variables {
let expr = {
let variable = *variable;
let app = ExpectReplApp {
memory: arena.alloc(memory),
start_offset,
};
let app = arena.alloc(app);
let content = subs.get_content_without_compacting(variable);
let mut layout_cache = LayoutCache::new(target_info);
@ -64,11 +61,6 @@ pub fn get_values<'a>(
target_info,
)?;
start_offset += layout.stack_size(target_info) as usize;
let mut extra_offset = app.memory.extra_offset.borrow_mut();
start_offset += *extra_offset;
*extra_offset = 0;
element
};
@ -81,7 +73,6 @@ pub fn get_values<'a>(
#[derive(Clone)]
struct ExpectMemory {
start: *const u8,
extra_offset: RefCell<usize>,
}
macro_rules! deref_number {
@ -127,9 +118,9 @@ impl ReplAppMemory for ExpectMemory {
} else {
let offset = self.deref_usize(addr);
let length = self.deref_usize(addr + std::mem::size_of::<usize>());
let capacity = self.deref_usize(addr + std::mem::size_of::<usize>());
*self.extra_offset.borrow_mut() += capacity;
// we don't store extra capacity
// let capacity = self.deref_usize(addr + 2 * std::mem::size_of::<usize>());
unsafe {
let ptr = self.start.add(offset);
@ -143,7 +134,7 @@ impl ReplAppMemory for ExpectMemory {
struct ExpectReplApp<'a> {
memory: &'a ExpectMemory,
start_offset: usize,
offset: usize,
}
impl<'a> ReplApp<'a> for ExpectReplApp<'a> {
@ -153,21 +144,23 @@ impl<'a> ReplApp<'a> for ExpectReplApp<'a> {
/// Size of the return value is statically determined from its Rust type
/// The `transform` callback takes the app's memory and the returned value
/// _main_fn_name is always the same and we don't use it here
fn call_function<Return, F>(&self, _main_fn_name: &str, transform: F) -> Expr<'a>
fn call_function<Return, F>(&mut self, _main_fn_name: &str, transform: F) -> Expr<'a>
where
F: Fn(&'a Self::Memory, Return) -> Expr<'a>,
Self::Memory: 'a,
{
let result: Return = unsafe {
let ptr = self.memory.start.add(self.start_offset);
let ptr = self.memory.start.add(self.offset);
let ptr: *const Return = std::mem::transmute(ptr);
ptr.read()
};
self.offset += std::mem::size_of::<Return>();
transform(self.memory, result)
}
fn call_function_returns_roc_list<F>(&self, main_fn_name: &str, transform: F) -> Expr<'a>
fn call_function_returns_roc_list<F>(&mut self, main_fn_name: &str, transform: F) -> Expr<'a>
where
F: Fn(&'a Self::Memory, (usize, usize, usize)) -> Expr<'a>,
Self::Memory: 'a,
@ -176,8 +169,8 @@ impl<'a> ReplApp<'a> for ExpectReplApp<'a> {
}
fn call_function_returns_roc_str<T, F>(
&self,
target_info: TargetInfo,
&mut self,
_target_info: TargetInfo,
main_fn_name: &str,
transform: F,
) -> T
@ -185,12 +178,25 @@ impl<'a> ReplApp<'a> for ExpectReplApp<'a> {
F: Fn(&'a Self::Memory, usize) -> T,
Self::Memory: 'a,
{
let roc_str_width = match target_info.ptr_width() {
roc_target::PtrWidth::Bytes4 => 12,
roc_target::PtrWidth::Bytes8 => 24,
};
let string_length = RefCell::new(0);
self.call_function_dynamic_size(main_fn_name, roc_str_width, transform)
let result = self.call_function_dynamic_size(main_fn_name, 24, |memory, addr| {
let last_byte_addr = addr + (3 * std::mem::size_of::<usize>()) - 1;
let last_byte = memory.deref_i8(last_byte_addr);
let is_small = last_byte < 0;
if !is_small {
let length = memory.deref_usize(addr + std::mem::size_of::<usize>());
*string_length.borrow_mut() = length;
}
transform(memory, addr)
});
self.offset += *string_length.borrow();
result
}
/// Run user code that returns a struct or union, whose size is provided as an argument
@ -198,15 +204,17 @@ impl<'a> ReplApp<'a> for ExpectReplApp<'a> {
/// _main_fn_name and _ret_bytes are only used for the CLI REPL. For Wasm they are compiled-in
/// to the test_wrapper function of the app itself
fn call_function_dynamic_size<T, F>(
&self,
&mut self,
_main_fn_name: &str,
_ret_bytes: usize,
ret_bytes: usize,
transform: F,
) -> T
where
F: Fn(&'a Self::Memory, usize) -> T,
Self::Memory: 'a,
{
transform(self.memory, self.start_offset)
let result = transform(self.memory, self.offset);
self.offset += ret_bytes;
result
}
}