Skip to content

Commit

Permalink
Problem: Allocation code is repeated all over the
Browse files Browse the repository at this point in the history
code base causing a lot of possibility for
mistakes.

Solution: Introduce a alloc and alloc_write macro
to make it easier.
  • Loading branch information
omarkj committed Feb 18, 2017
1 parent b1df9e2 commit 5bb0794
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 132 deletions.
20 changes: 20 additions & 0 deletions src/script/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,26 @@ macro_rules! write_size_header {
}};
}

macro_rules! alloc_slice {
($size: expr, $env: expr) => {{
let slice = $env.alloc($size);
if slice.is_err() {
return Err(($env, slice.unwrap_err()));
}
slice.unwrap()
}};
}

macro_rules! alloc_and_write {
($bytes: expr, $env: expr) => {{
let slice = alloc_slice!($bytes.len(), $env);
for i in 0..$bytes.len() {
slice[i] = $bytes[i];
}
slice
}};
}

#[cfg(test)]
macro_rules! eval {
($script: expr, $env: ident, $expr: expr) => {
Expand Down
140 changes: 38 additions & 102 deletions src/script/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -581,14 +581,7 @@ impl<'a> VM<'a> {
if program.len() == 0 {
return Ok((env, None));
}
let slice0 = env.alloc(program.len());
if slice0.is_err() {
return Err((env, slice0.unwrap_err()));
}
let mut slice = slice0.unwrap();
for i in 0..program.len() {
slice[i] = program[i];
}
let slice = alloc_and_write!(program, env);
if let nom::IResult::Done(_, data) = binparser::data(slice) {
if env.aborting_try.is_empty() {
env.push(&data[offset_by_size(data.len())..]);
Expand Down Expand Up @@ -750,14 +743,7 @@ impl<'a> VM<'a> {
fn handle_depth(&mut self, mut env: Env<'a>, word: &'a [u8], _: EnvId) -> PassResult<'a> {
word_is!(env, word, DEPTH);
let bytes = BigUint::from(env.stack_size).to_bytes_be();
let slice0 = env.alloc(bytes.len());
if slice0.is_err() {
return Err((env, slice0.unwrap_err()));
}
let mut slice = slice0.unwrap();
for i in 0..bytes.len() {
slice[i] = bytes[i];
}
let slice = alloc_and_write!(bytes, env);
env.push(slice);
Ok((env, None))
}
Expand All @@ -780,21 +766,18 @@ impl<'a> VM<'a> {
let size = vec.clone().into_iter()
.fold(0, |a, item| a + item.len() + offset_by_size(item.len()));

match env.alloc(size) {
Ok(mut slice) => {
let mut offset = 0;
for item in vec {
write_size_into_slice!(item.len(), &mut slice[offset..]);
offset += offset_by_size(item.len());
for b in item {
slice[offset] = *b;
offset += 1;
}
}
env.push(slice);
let mut slice = alloc_slice!(size, env);

let mut offset = 0;
for item in vec {
write_size_into_slice!(item.len(), &mut slice[offset..]);
offset += offset_by_size(item.len());
for b in item {
slice[offset] = *b;
offset += 1;
}
Err(err) => return Err((env, err))
}
env.push(slice);
Ok((env, None))
}

Expand Down Expand Up @@ -927,11 +910,7 @@ impl<'a> VM<'a> {
let a = stack_pop!(env);
let b = stack_pop!(env);

let slice0 = env.alloc(a.len() + b.len());
if slice0.is_err() {
return Err((env, slice0.unwrap_err()));
}
let mut slice = slice0.unwrap();
let slice = alloc_slice!(a.len() + b.len(), env);
let mut offset = 0;

for byte in b {
Expand Down Expand Up @@ -985,18 +964,7 @@ impl<'a> VM<'a> {
let len = BigUint::from(a.len() as u64);
let len_bytes = len.to_bytes_be();

let slice0 = env.alloc(len_bytes.len());
if slice0.is_err() {
return Err((env, slice0.unwrap_err()));
}
let mut slice = slice0.unwrap();

let mut offset = 0;

for byte in len_bytes {
slice[offset] = byte;
offset += 1
}
let slice = alloc_and_write!(len_bytes, env);

env.push(slice);

Expand Down Expand Up @@ -1050,18 +1018,9 @@ impl<'a> VM<'a> {

let c_bytes = c_uint.to_bytes_be();

match env.alloc(c_bytes.len()) {
Ok(slice) => {
let mut i = 0;
for byte in c_bytes {
slice[i] = byte;
i += 1;
}
env.push(slice);
Ok((env, None))
}
Err(err) => Err((env, err))
}
let slice = alloc_and_write!(c_bytes, env);
env.push(slice);
Ok((env, None))
}

#[inline]
Expand All @@ -1080,19 +1039,9 @@ impl<'a> VM<'a> {
let c_uint = b_uint.sub(a_uint);

let c_bytes = c_uint.to_bytes_be();

match env.alloc(c_bytes.len()) {
Ok(slice) => {
let mut i = 0;
for byte in c_bytes {
slice[i] = byte;
i += 1;
}
env.push(slice);
Ok((env, None))
}
Err(err) => Err((env, err))
}
let slice = alloc_and_write!(c_bytes, env);
env.push(slice);
Ok((env, None))
}


Expand Down Expand Up @@ -1135,18 +1084,9 @@ impl<'a> VM<'a> {
env.push(_EMPTY);
Ok((env, None))
} else if let Some(Error::ProgramError(err)) = env.aborting_try.pop() {
match env.alloc(err.len()) {
Ok(slice) => {
let mut i = 0;
for byte in err {
slice[i] = byte;
i += 1;
}
env.push(slice);
Ok((env, None))
}
Err(err) => Err((env, err))
}
let slice = alloc_and_write!(err, env);
env.push(slice);
Ok((env, None))
} else {
env.push(_EMPTY);
Ok((env, None))
Expand Down Expand Up @@ -1240,26 +1180,22 @@ impl<'a> VM<'a> {
let value = stack_pop!(env);
match binparser::word(word) {
nom::IResult::Done(_, _) => {
match env.alloc(value.len() + offset_by_size(value.len())) {
Ok(mut slice) => {
write_size_into_slice!(value.len(), slice);
let mut offset = offset_by_size(value.len());
for b in value {
slice[offset] = *b;
offset += 1;
}
#[cfg(feature = "scoped_dictionary")]
{
let mut dict = env.dictionary.pop().unwrap();
dict.insert(word, slice);
env.dictionary.push(dict);
}
#[cfg(not(feature = "scoped_dictionary"))]
env.dictionary.insert(word, slice);
Ok((env, None))
}
Err(err) => return Err((env, err))
let slice = alloc_slice!(value.len() + offset_by_size(value.len()), env);
write_size_into_slice!(value.len(), slice);
let mut offset = offset_by_size(value.len());
for b in value {
slice[offset] = *b;
offset += 1;
}
#[cfg(feature = "scoped_dictionary")]
{
let mut dict = env.dictionary.pop().unwrap();
dict.insert(word, slice);
env.dictionary.push(dict);
}
#[cfg(not(feature = "scoped_dictionary"))]
env.dictionary.insert(word, slice);
Ok((env, None))
},
_ => Err((env, error_invalid_value!(word)))
}
Expand Down
18 changes: 3 additions & 15 deletions src/script/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ macro_rules! cursor_op {
Ok((key, val)) => {
let mut offset = 0;
let sz = key.len() + val.len() + offset_by_size(key.len()) + offset_by_size(val.len());
let slice = $env.alloc(sz).unwrap();
let slice = alloc_slice!(sz, $env);
write_size_into_slice!(key.len(), &mut slice[offset..]);
offset += offset_by_size(key.len());
for i in 0..key.len() {
Expand Down Expand Up @@ -329,14 +329,7 @@ impl<'a> Handler<'a> {

return match access.get::<[u8], [u8]>(self.db, key).to_opt() {
Ok(Some(val)) => {
let slice0 = env.alloc(val.len());
if slice0.is_err() {
return Err((env, slice0.unwrap_err()))
}
let mut slice = slice0.unwrap();
for i in 0..val.len() {
slice[i] = val[i];
}
let slice = alloc_and_write!(val, env);
env.push(slice);
Ok((env, None))
}
Expand Down Expand Up @@ -396,12 +389,7 @@ impl<'a> Handler<'a> {
}
let _ = bytes.write_u64::<BigEndian>(id.offset);
self.cursors.insert((pid.clone(), bytes.clone()), (tx_type!(self, env), Handler::cast_away(cursor)));
let slice = env.alloc(bytes.len()).unwrap();
let mut i = 0;
for byte in bytes {
slice[i] = byte;
i += 1;
}
let slice = alloc_and_write!(bytes, env);
env.push(slice);
Ok((env, None))
},
Expand Down
18 changes: 3 additions & 15 deletions src/script/timestamp_hlc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,7 @@ impl<'a> Handler<'a> {
pub fn handle_hlc(&mut self, mut env: Env<'a>, word: &'a [u8], _: EnvId) -> PassResult<'a> {
if word == HLC {
let now = timestamp::hlc();
let slice0 = env.alloc(16);
if slice0.is_err() {
return Err((env, slice0.unwrap_err()));
}
let mut slice = slice0.unwrap();
let slice = alloc_slice!(16, env);
let _ = now.write_bytes(&mut slice[0..]).unwrap();
env.push(slice);
Ok((env, None))
Expand Down Expand Up @@ -147,11 +143,7 @@ impl<'a> Handler<'a> {
let mut t1 = t1_.unwrap();
t1.count += 1;

let slice0 = env.alloc(16);
if slice0.is_err() {
return Err((env, slice0.unwrap_err()));
}
let slice = slice0.unwrap();
let slice = alloc_slice!(16, env);
let _ = t1.write_bytes(&mut slice[0..]).unwrap();
env.push(slice);

Expand Down Expand Up @@ -180,11 +172,7 @@ impl<'a> Handler<'a> {

let t1 = t1_.unwrap();

let slice0 = env.alloc(4);
if slice0.is_err() {
return Err((env, slice0.unwrap_err()));
}
let slice = slice0.unwrap();
let slice = alloc_slice!(4, env);
let _ = (&mut slice[0..]).write_u32::<BigEndian>(t1.count);

env.push(slice);
Expand Down

0 comments on commit 5bb0794

Please sign in to comment.