|  |  |  | @ -1,19 +1,25 @@ | 
			
		
	
		
			
				
					|  |  |  |  | use std::collections::{HashMap, VecDeque}; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | use crsn::asm::data::literal::Value; | 
			
		
	
		
			
				
					|  |  |  |  | use crsn::asm::instr::cond::Flag; | 
			
		
	
		
			
				
					|  |  |  |  | use crsn::module::{EvalRes, OpTrait}; | 
			
		
	
		
			
				
					|  |  |  |  | use crsn::runtime::fault::Fault; | 
			
		
	
		
			
				
					|  |  |  |  | use crsn::runtime::run_thread::{state::RunState, ThreadInfo}; | 
			
		
	
		
			
				
					|  |  |  |  | use crsn::sexp; | 
			
		
	
		
			
				
					|  |  |  |  | use crsn::sexp::{Sexp, atom_qs}; | 
			
		
	
		
			
				
					|  |  |  |  | use crsn::sexp::{atom_qs, Sexp}; | 
			
		
	
		
			
				
					|  |  |  |  | use crsn::utils::A; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | use crate::defs::{BufOps, BufValue}; | 
			
		
	
		
			
				
					|  |  |  |  | use crsn::asm::instr::cond::Flag; | 
			
		
	
		
			
				
					|  |  |  |  | use crate::defs::{BufIoMode, BufOps, BufValue}; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | #[derive(Debug, Default, Clone)] | 
			
		
	
		
			
				
					|  |  |  |  | struct Buffer { | 
			
		
	
		
			
				
					|  |  |  |  |     data: VecDeque<Value>, | 
			
		
	
		
			
				
					|  |  |  |  |     iomode: BufIoMode, | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | #[derive(Debug, Default)] | 
			
		
	
		
			
				
					|  |  |  |  | struct ExtData { | 
			
		
	
		
			
				
					|  |  |  |  |     store: HashMap<Value, VecDeque<Value>>, | 
			
		
	
		
			
				
					|  |  |  |  |     buffers: HashMap<Value, Buffer>, | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | // TODO optimize and DRY
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -49,26 +55,38 @@ impl OpTrait for BufOps { | 
			
		
	
		
			
				
					|  |  |  |  |                 }; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 let data: &mut ExtData = state.ext_mut(); | 
			
		
	
		
			
				
					|  |  |  |  |                 data.store.insert(id, que); | 
			
		
	
		
			
				
					|  |  |  |  |                 data.buffers.insert(id, Buffer { | 
			
		
	
		
			
				
					|  |  |  |  |                     data: que, | 
			
		
	
		
			
				
					|  |  |  |  |                     iomode: Default::default() | 
			
		
	
		
			
				
					|  |  |  |  |                 }); | 
			
		
	
		
			
				
					|  |  |  |  |                 state.write(dst, id)?; | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             BufOps::SetIoMode { obj, mode } => { | 
			
		
	
		
			
				
					|  |  |  |  |                 state.clear_status(); | 
			
		
	
		
			
				
					|  |  |  |  |                 let handle = state.read_obj(obj)?; | 
			
		
	
		
			
				
					|  |  |  |  |                 let store: &mut ExtData = state.ext_mut(); | 
			
		
	
		
			
				
					|  |  |  |  |                 let buf = store.buffers.get_mut(&handle).ok_or_else(|| Fault::ObjectNotExist(handle))?; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |                 buf.iomode = *mode; | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             BufOps::Push { obj, src } => { | 
			
		
	
		
			
				
					|  |  |  |  |                 state.clear_status(); | 
			
		
	
		
			
				
					|  |  |  |  |                 let val = state.read(src)?; | 
			
		
	
		
			
				
					|  |  |  |  |                 let handle = state.read_obj(obj)?; | 
			
		
	
		
			
				
					|  |  |  |  |                 let stacks: &mut ExtData = state.ext_mut(); | 
			
		
	
		
			
				
					|  |  |  |  |                 let stack = stacks.store.get_mut(&handle).ok_or_else(|| Fault::ObjectNotExist(handle))?; | 
			
		
	
		
			
				
					|  |  |  |  |                 stack.push_back(val); | 
			
		
	
		
			
				
					|  |  |  |  |                 let store: &mut ExtData = state.ext_mut(); | 
			
		
	
		
			
				
					|  |  |  |  |                 let buf = store.buffers.get_mut(&handle).ok_or_else(|| Fault::ObjectNotExist(handle))?; | 
			
		
	
		
			
				
					|  |  |  |  |                 buf.data.push_back(val); | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             BufOps::Pop { dst, obj } => { | 
			
		
	
		
			
				
					|  |  |  |  |                 state.clear_status(); | 
			
		
	
		
			
				
					|  |  |  |  |                 let handle = state.read_obj(obj)?; | 
			
		
	
		
			
				
					|  |  |  |  |                 let stacks: &mut ExtData = state.ext_mut(); | 
			
		
	
		
			
				
					|  |  |  |  |                 let stack = stacks.store.get_mut(&handle).ok_or_else(|| Fault::ObjectNotExist(handle))?; | 
			
		
	
		
			
				
					|  |  |  |  |                 if let Some(val) = stack.pop_back() { | 
			
		
	
		
			
				
					|  |  |  |  |                     let empty = stack.is_empty(); | 
			
		
	
		
			
				
					|  |  |  |  |                 let store: &mut ExtData = state.ext_mut(); | 
			
		
	
		
			
				
					|  |  |  |  |                 let buf = store.buffers.get_mut(&handle).ok_or_else(|| Fault::ObjectNotExist(handle))?; | 
			
		
	
		
			
				
					|  |  |  |  |                 if let Some(val) = buf.data.pop_back() { | 
			
		
	
		
			
				
					|  |  |  |  |                     let empty = buf.data.is_empty(); | 
			
		
	
		
			
				
					|  |  |  |  |                     state.write(dst, val)?; | 
			
		
	
		
			
				
					|  |  |  |  |                     state.update_status(val); | 
			
		
	
		
			
				
					|  |  |  |  |                     state.set_flag(Flag::Empty, empty); | 
			
		
	
	
		
			
				
					|  |  |  | @ -82,9 +100,9 @@ impl OpTrait for BufOps { | 
			
		
	
		
			
				
					|  |  |  |  |                 state.clear_status(); | 
			
		
	
		
			
				
					|  |  |  |  |                 let handle = state.read_obj(obj)?; | 
			
		
	
		
			
				
					|  |  |  |  |                 let idx = state.read(idx)?; | 
			
		
	
		
			
				
					|  |  |  |  |                 let stacks: &mut ExtData = state.ext_mut(); | 
			
		
	
		
			
				
					|  |  |  |  |                 let stack = stacks.store.get(&handle).ok_or_else(|| Fault::ObjectNotExist(handle))?; | 
			
		
	
		
			
				
					|  |  |  |  |                 if let Some(val) = stack.get(idx as usize) { | 
			
		
	
		
			
				
					|  |  |  |  |                 let store: &mut ExtData = state.ext_mut(); | 
			
		
	
		
			
				
					|  |  |  |  |                 let buf = store.buffers.get(&handle).ok_or_else(|| Fault::ObjectNotExist(handle))?; | 
			
		
	
		
			
				
					|  |  |  |  |                 if let Some(val) = buf.data.get(idx as usize) { | 
			
		
	
		
			
				
					|  |  |  |  |                     let val = *val; | 
			
		
	
		
			
				
					|  |  |  |  |                     state.update_status(val); | 
			
		
	
		
			
				
					|  |  |  |  |                     state.write(dst, val)?; | 
			
		
	
	
		
			
				
					|  |  |  | @ -96,9 +114,9 @@ impl OpTrait for BufOps { | 
			
		
	
		
			
				
					|  |  |  |  |             BufOps::GetLen { dst, obj } => { | 
			
		
	
		
			
				
					|  |  |  |  |                 state.clear_status(); | 
			
		
	
		
			
				
					|  |  |  |  |                 let handle = state.read_obj(obj)?; | 
			
		
	
		
			
				
					|  |  |  |  |                 let stacks: &mut ExtData = state.ext_mut(); | 
			
		
	
		
			
				
					|  |  |  |  |                 let stack = stacks.store.get(&handle).ok_or_else(|| Fault::ObjectNotExist(handle))?; | 
			
		
	
		
			
				
					|  |  |  |  |                 let val = stack.len() as Value; | 
			
		
	
		
			
				
					|  |  |  |  |                 let store: &mut ExtData = state.ext_mut(); | 
			
		
	
		
			
				
					|  |  |  |  |                 let buf = store.buffers.get(&handle).ok_or_else(|| Fault::ObjectNotExist(handle))?; | 
			
		
	
		
			
				
					|  |  |  |  |                 let val = buf.data.len() as Value; | 
			
		
	
		
			
				
					|  |  |  |  |                 state.write(dst, val)?; | 
			
		
	
		
			
				
					|  |  |  |  |                 state.update_status(val); | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
	
		
			
				
					|  |  |  | @ -108,12 +126,12 @@ impl OpTrait for BufOps { | 
			
		
	
		
			
				
					|  |  |  |  |                 let handle = state.read_obj(obj)?; | 
			
		
	
		
			
				
					|  |  |  |  |                 let val = state.read(value)?; | 
			
		
	
		
			
				
					|  |  |  |  |                 let idx = state.read(idx)? as usize; | 
			
		
	
		
			
				
					|  |  |  |  |                 let stacks: &mut ExtData = state.ext_mut(); | 
			
		
	
		
			
				
					|  |  |  |  |                 let stack = stacks.store.get_mut(&handle).ok_or_else(|| Fault::ObjectNotExist(handle))?; | 
			
		
	
		
			
				
					|  |  |  |  |                 if idx < stack.len() { | 
			
		
	
		
			
				
					|  |  |  |  |                     stack[idx] = val; | 
			
		
	
		
			
				
					|  |  |  |  |                 } else if idx == stack.len() { | 
			
		
	
		
			
				
					|  |  |  |  |                     stack.push_back(val); | 
			
		
	
		
			
				
					|  |  |  |  |                 let store: &mut ExtData = state.ext_mut(); | 
			
		
	
		
			
				
					|  |  |  |  |                 let buf = store.buffers.get_mut(&handle).ok_or_else(|| Fault::ObjectNotExist(handle))?; | 
			
		
	
		
			
				
					|  |  |  |  |                 if idx < buf.data.len() { | 
			
		
	
		
			
				
					|  |  |  |  |                     buf.data[idx] = val; | 
			
		
	
		
			
				
					|  |  |  |  |                 } else if idx == buf.data.len() { | 
			
		
	
		
			
				
					|  |  |  |  |                     buf.data.push_back(val); | 
			
		
	
		
			
				
					|  |  |  |  |                 } else { | 
			
		
	
		
			
				
					|  |  |  |  |                     state.set_flag(Flag::Overflow, true); | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
	
		
			
				
					|  |  |  | @ -124,12 +142,12 @@ impl OpTrait for BufOps { | 
			
		
	
		
			
				
					|  |  |  |  |                 let handle = state.read_obj(obj)?; | 
			
		
	
		
			
				
					|  |  |  |  |                 let val = state.read(value)?; | 
			
		
	
		
			
				
					|  |  |  |  |                 let idx = state.read(idx)? as usize; | 
			
		
	
		
			
				
					|  |  |  |  |                 let stacks: &mut ExtData = state.ext_mut(); | 
			
		
	
		
			
				
					|  |  |  |  |                 let stack = stacks.store.get_mut(&handle).ok_or_else(|| Fault::ObjectNotExist(handle))?; | 
			
		
	
		
			
				
					|  |  |  |  |                 if idx < stack.len() { | 
			
		
	
		
			
				
					|  |  |  |  |                     stack.insert(idx, val); | 
			
		
	
		
			
				
					|  |  |  |  |                 } else if idx == stack.len() { | 
			
		
	
		
			
				
					|  |  |  |  |                     stack.push_back(val); | 
			
		
	
		
			
				
					|  |  |  |  |                 let store: &mut ExtData = state.ext_mut(); | 
			
		
	
		
			
				
					|  |  |  |  |                 let buf = store.buffers.get_mut(&handle).ok_or_else(|| Fault::ObjectNotExist(handle))?; | 
			
		
	
		
			
				
					|  |  |  |  |                 if idx < buf.data.len() { | 
			
		
	
		
			
				
					|  |  |  |  |                     buf.data.insert(idx, val); | 
			
		
	
		
			
				
					|  |  |  |  |                 } else if idx == buf.data.len() { | 
			
		
	
		
			
				
					|  |  |  |  |                     buf.data.push_back(val); | 
			
		
	
		
			
				
					|  |  |  |  |                 } else { | 
			
		
	
		
			
				
					|  |  |  |  |                     state.set_flag(Flag::Overflow, true); | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
	
		
			
				
					|  |  |  | @ -139,11 +157,11 @@ impl OpTrait for BufOps { | 
			
		
	
		
			
				
					|  |  |  |  |                 state.clear_status(); | 
			
		
	
		
			
				
					|  |  |  |  |                 let handle = state.read_obj(obj)?; | 
			
		
	
		
			
				
					|  |  |  |  |                 let idx = state.read(idx)? as usize; | 
			
		
	
		
			
				
					|  |  |  |  |                 let stacks: &mut ExtData = state.ext_mut(); | 
			
		
	
		
			
				
					|  |  |  |  |                 let stack = stacks.store.get_mut(&handle).ok_or_else(|| Fault::ObjectNotExist(handle))?; | 
			
		
	
		
			
				
					|  |  |  |  |                 if idx < stack.len() { | 
			
		
	
		
			
				
					|  |  |  |  |                     let val = stack.remove(idx).unwrap(); | 
			
		
	
		
			
				
					|  |  |  |  |                     let empty = stack.is_empty(); | 
			
		
	
		
			
				
					|  |  |  |  |                 let store: &mut ExtData = state.ext_mut(); | 
			
		
	
		
			
				
					|  |  |  |  |                 let buf = store.buffers.get_mut(&handle).ok_or_else(|| Fault::ObjectNotExist(handle))?; | 
			
		
	
		
			
				
					|  |  |  |  |                 if idx < buf.data.len() { | 
			
		
	
		
			
				
					|  |  |  |  |                     let val = buf.data.remove(idx).unwrap(); | 
			
		
	
		
			
				
					|  |  |  |  |                     let empty = buf.data.is_empty(); | 
			
		
	
		
			
				
					|  |  |  |  |                     state.update_status(val); | 
			
		
	
		
			
				
					|  |  |  |  |                     state.write(dst, val)?; | 
			
		
	
		
			
				
					|  |  |  |  |                     state.set_flag(Flag::Empty, empty); | 
			
		
	
	
		
			
				
					|  |  |  | @ -155,21 +173,21 @@ impl OpTrait for BufOps { | 
			
		
	
		
			
				
					|  |  |  |  |             BufOps::Resize { obj, len } => { | 
			
		
	
		
			
				
					|  |  |  |  |                 let handle = state.read_obj(obj)?; | 
			
		
	
		
			
				
					|  |  |  |  |                 let len = state.read(len)? as usize; | 
			
		
	
		
			
				
					|  |  |  |  |                 let stacks: &mut ExtData = state.ext_mut(); | 
			
		
	
		
			
				
					|  |  |  |  |                 let stack = stacks.store.get_mut(&handle).ok_or_else(|| Fault::ObjectNotExist(handle))?; | 
			
		
	
		
			
				
					|  |  |  |  |                 stack.resize(len, 0); | 
			
		
	
		
			
				
					|  |  |  |  |                 let store: &mut ExtData = state.ext_mut(); | 
			
		
	
		
			
				
					|  |  |  |  |                 let buf = store.buffers.get_mut(&handle).ok_or_else(|| Fault::ObjectNotExist(handle))?; | 
			
		
	
		
			
				
					|  |  |  |  |                 buf.data.resize(len, 0); | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             BufOps::Reverse { obj } => { | 
			
		
	
		
			
				
					|  |  |  |  |                 let handle = state.read_obj(obj)?; | 
			
		
	
		
			
				
					|  |  |  |  |                 let stacks: &mut ExtData = state.ext_mut(); | 
			
		
	
		
			
				
					|  |  |  |  |                 let stack = stacks.store.get_mut(&handle).ok_or_else(|| Fault::ObjectNotExist(handle))?; | 
			
		
	
		
			
				
					|  |  |  |  |                 let len = stack.len(); | 
			
		
	
		
			
				
					|  |  |  |  |                 let store: &mut ExtData = state.ext_mut(); | 
			
		
	
		
			
				
					|  |  |  |  |                 let buf = store.buffers.get_mut(&handle).ok_or_else(|| Fault::ObjectNotExist(handle))?; | 
			
		
	
		
			
				
					|  |  |  |  |                 let len = buf.data.len(); | 
			
		
	
		
			
				
					|  |  |  |  |                 if len > 1 { | 
			
		
	
		
			
				
					|  |  |  |  |                     let mut start = 0; | 
			
		
	
		
			
				
					|  |  |  |  |                     let mut end = len - 1; | 
			
		
	
		
			
				
					|  |  |  |  |                     while start < end { | 
			
		
	
		
			
				
					|  |  |  |  |                         stack.swap(start, end); | 
			
		
	
		
			
				
					|  |  |  |  |                         buf.data.swap(start, end); | 
			
		
	
		
			
				
					|  |  |  |  |                         start += 1; | 
			
		
	
		
			
				
					|  |  |  |  |                         end -= 1; | 
			
		
	
		
			
				
					|  |  |  |  |                     } | 
			
		
	
	
		
			
				
					|  |  |  | @ -179,20 +197,22 @@ impl OpTrait for BufOps { | 
			
		
	
		
			
				
					|  |  |  |  |             BufOps::AppendBuf { obj, obj2 } => { | 
			
		
	
		
			
				
					|  |  |  |  |                 let handle = state.read_obj(obj)?; | 
			
		
	
		
			
				
					|  |  |  |  |                 let handle2 = state.read_obj(obj2)?; | 
			
		
	
		
			
				
					|  |  |  |  |                 let stacks: &mut ExtData = state.ext_mut(); | 
			
		
	
		
			
				
					|  |  |  |  |                 let stack2 = stacks.store.get(&handle2).ok_or_else(|| Fault::ObjectNotExist(handle))?.clone(); | 
			
		
	
		
			
				
					|  |  |  |  |                 let stack = stacks.store.get_mut(&handle).ok_or_else(|| Fault::ObjectNotExist(handle))?; | 
			
		
	
		
			
				
					|  |  |  |  |                 stack.extend(stack2); | 
			
		
	
		
			
				
					|  |  |  |  |                 let store: &mut ExtData = state.ext_mut(); | 
			
		
	
		
			
				
					|  |  |  |  |                 // TODO figure out how to avoid cloning
 | 
			
		
	
		
			
				
					|  |  |  |  |                 let buf2 = store.buffers.get(&handle2).ok_or_else(|| Fault::ObjectNotExist(handle))?.data.clone(); | 
			
		
	
		
			
				
					|  |  |  |  |                 let buf = store.buffers.get_mut(&handle).ok_or_else(|| Fault::ObjectNotExist(handle))?; | 
			
		
	
		
			
				
					|  |  |  |  |                 buf.data.extend(buf2); | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |             BufOps::PrependBuf { obj, obj2 } => { | 
			
		
	
		
			
				
					|  |  |  |  |                 let handle = state.read_obj(obj)?; | 
			
		
	
		
			
				
					|  |  |  |  |                 let handle2 = state.read_obj(obj2)?; | 
			
		
	
		
			
				
					|  |  |  |  |                 let stacks: &mut ExtData = state.ext_mut(); | 
			
		
	
		
			
				
					|  |  |  |  |                 let stack2 = stacks.store.get(&handle2).ok_or_else(|| Fault::ObjectNotExist(handle))?.clone(); | 
			
		
	
		
			
				
					|  |  |  |  |                 let stack = stacks.store.get_mut(&handle).ok_or_else(|| Fault::ObjectNotExist(handle))?; | 
			
		
	
		
			
				
					|  |  |  |  |                 for v in stack2.into_iter().rev() { | 
			
		
	
		
			
				
					|  |  |  |  |                     stack.push_front(v); | 
			
		
	
		
			
				
					|  |  |  |  |                 let store: &mut ExtData = state.ext_mut(); | 
			
		
	
		
			
				
					|  |  |  |  |                 // TODO figure out how to avoid cloning
 | 
			
		
	
		
			
				
					|  |  |  |  |                 let buf2 = store.buffers.get(&handle2).ok_or_else(|| Fault::ObjectNotExist(handle))?.data.clone(); | 
			
		
	
		
			
				
					|  |  |  |  |                 let buf = store.buffers.get_mut(&handle).ok_or_else(|| Fault::ObjectNotExist(handle))?; | 
			
		
	
		
			
				
					|  |  |  |  |                 for v in buf2.into_iter().rev() { | 
			
		
	
		
			
				
					|  |  |  |  |                     buf.data.push_front(v); | 
			
		
	
		
			
				
					|  |  |  |  |                 } | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
	
		
			
				
					|  |  |  | @ -257,12 +277,61 @@ impl OpTrait for BufOps { | 
			
		
	
		
			
				
					|  |  |  |  |             BufOps::PrependBuf { obj, obj2 } => { | 
			
		
	
		
			
				
					|  |  |  |  |                 sexp::list(&[A("bfprep"), A(obj), A(obj2)]) | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |             BufOps::SetIoMode { obj, mode } => { | 
			
		
	
		
			
				
					|  |  |  |  |                 sexp::list(&[A("bfio"), A(obj), A(mode.to_value())]) | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | pub(crate) fn drop_obj(state: &mut RunState, handle: Value) -> Result<Option<()>, Fault> { | 
			
		
	
		
			
				
					|  |  |  |  |     let stacks: &mut ExtData = state.ext_mut(); | 
			
		
	
		
			
				
					|  |  |  |  |     Ok(stacks.store.remove(&handle).map(|_| ())) | 
			
		
	
		
			
				
					|  |  |  |  |     let store: &mut ExtData = state.ext_mut(); | 
			
		
	
		
			
				
					|  |  |  |  |     Ok(store.buffers.remove(&handle).map(|_| ())) | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | /// Run-time method called to read an object (using the object handle syntax)
 | 
			
		
	
		
			
				
					|  |  |  |  | pub(crate) fn read_obj(state: &mut RunState, handle: Value) | 
			
		
	
		
			
				
					|  |  |  |  |             -> Result<Option<Value>, Fault> | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  |     let store: &mut ExtData = state.ext_mut(); | 
			
		
	
		
			
				
					|  |  |  |  |     if let Some(buf) = store.buffers.get_mut(&handle) { | 
			
		
	
		
			
				
					|  |  |  |  |         match match buf.iomode { | 
			
		
	
		
			
				
					|  |  |  |  |             BufIoMode::Queue => buf.data.pop_front(), | 
			
		
	
		
			
				
					|  |  |  |  |             BufIoMode::ReverseQueue => buf.data.pop_back(), | 
			
		
	
		
			
				
					|  |  |  |  |             BufIoMode::Stack => buf.data.pop_back(), | 
			
		
	
		
			
				
					|  |  |  |  |             BufIoMode::ReverseStack => buf.data.pop_front() | 
			
		
	
		
			
				
					|  |  |  |  |         } { | 
			
		
	
		
			
				
					|  |  |  |  |             None => { | 
			
		
	
		
			
				
					|  |  |  |  |                 state.set_flag(Flag::Overflow, true); | 
			
		
	
		
			
				
					|  |  |  |  |                 state.set_flag(Flag::Empty, true); | 
			
		
	
		
			
				
					|  |  |  |  |                 Ok(Some(0)) | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |             Some(val) => { | 
			
		
	
		
			
				
					|  |  |  |  |                 let em = buf.data.is_empty(); | 
			
		
	
		
			
				
					|  |  |  |  |                 state.set_flag(Flag::Empty, em); | 
			
		
	
		
			
				
					|  |  |  |  |                 Ok(Some(val)) | 
			
		
	
		
			
				
					|  |  |  |  |             } | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  |     } else { | 
			
		
	
		
			
				
					|  |  |  |  |         Ok(None) | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | /// Run-time method called to write an object (using the object handle syntax)
 | 
			
		
	
		
			
				
					|  |  |  |  | pub(crate) fn write_obj(state: &mut RunState, handle: Value, value: Value) -> Result<Option<()>, Fault> | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  |     let store: &mut ExtData = state.ext_mut(); | 
			
		
	
		
			
				
					|  |  |  |  |     if let Some(buf) = store.buffers.get_mut(&handle) { | 
			
		
	
		
			
				
					|  |  |  |  |         match buf.iomode { | 
			
		
	
		
			
				
					|  |  |  |  |             BufIoMode::Queue => buf.data.push_back(value), | 
			
		
	
		
			
				
					|  |  |  |  |             BufIoMode::ReverseQueue => buf.data.push_front(value), | 
			
		
	
		
			
				
					|  |  |  |  |             BufIoMode::Stack => buf.data.push_back(value), | 
			
		
	
		
			
				
					|  |  |  |  |             BufIoMode::ReverseStack => buf.data.push_front(value) | 
			
		
	
		
			
				
					|  |  |  |  |         } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  |         Ok(Some(())) | 
			
		
	
		
			
				
					|  |  |  |  |     } else { | 
			
		
	
		
			
				
					|  |  |  |  |         Ok(None) | 
			
		
	
		
			
				
					|  |  |  |  |     } | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
	
		
			
				
					|  |  |  | 
 |