housekeeping, pr fixes

This commit is contained in:
vms
2021-04-21 19:18:45 +03:00
parent a48662d48c
commit 8de882c159
13 changed files with 225 additions and 172 deletions

View File

@ -1,4 +1,21 @@
/*
* Copyright 2021 Fluence Labs Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
pub mod error;
mod macros;
pub mod memory_reader;
pub mod memory_writer;
@ -45,7 +62,7 @@ pub fn record_size(record_type: &IRecordType) -> usize {
}
pub fn type_tag_form_itype(itype: &IType) -> u32 {
const POINTER_CODE: u32 = 3; // u32 on the sdk
const POINTER_CODE: u32 = 3; // u32 in the sdk
match itype {
IType::Boolean => 0, // u8
@ -64,7 +81,7 @@ pub fn type_tag_form_itype(itype: &IType) -> u32 {
}
pub fn type_tag_form_ivalue(itype: &IValue) -> u32 {
const POINTER_CODE: u32 = 3; // u32 on the sdk
const POINTER_CODE: u32 = 3; // u32 in the sdk
match itype {
IValue::Boolean(_) => 0, // u8

View File

@ -0,0 +1,103 @@
/*
* Copyright 2021 Fluence Labs Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#[macro_export]
macro_rules! value_der {
($self:expr, $offset:expr, @seq_start $($ids:tt),* @seq_end) => {
[$($self.reader.memory[$offset + $ids].get()),+]
};
($self:expr, $offset:expr, 1) => {
crate::value_der!($self, $offset, @seq_start 0 @seq_end);
};
($self:expr, $offset:expr, 2) => {
crate::value_der!($self, $offset, @seq_start 0, 1 @seq_end);
};
($self:expr, $offset:expr, 4) => {
crate::value_der!($self, $offset, @seq_start 0, 1, 2, 3 @seq_end);
};
($self:expr, $offset:expr, 8) => {
crate::value_der!($self, $offset, @seq_start 0, 1, 2, 3, 4, 5, 6, 7 @seq_end);
};
}
#[macro_export]
macro_rules! read_ty {
($func_name:ident, $ty:ty, 1) => {
pub fn $func_name(&self) -> $ty {
let offset = self.offset.get();
let result = <$ty>::from_le_bytes(crate::value_der!(self, offset, 1));
self.offset.set(offset + 1);
result
}
};
($func_name:ident, $ty:ty, 2) => {
pub fn $func_name(&self) -> $ty {
let offset = self.offset.get();
let result = <$ty>::from_le_bytes(crate::value_der!(self, offset, 2));
self.offset.set(offset + 2);
result
}
};
($func_name:ident, $ty:ty, 4) => {
pub fn $func_name(&self) -> $ty {
let offset = self.offset.get();
let result = <$ty>::from_le_bytes(crate::value_der!(self, offset, 4));
self.offset.set(offset + 4);
result
}
};
($func_name:ident, $ty:ty, 8) => {
pub fn $func_name(&self) -> $ty {
let offset = self.offset.get();
let result = <$ty>::from_le_bytes(crate::value_der!(self, offset, 8));
self.offset.set(offset + 8);
result
}
};
}
#[macro_export]
macro_rules! read_array_ty {
($func_name:ident, $ty:ident, $ity:ident) => {
pub fn $func_name(
&self,
offset: usize,
elements_count: usize,
) -> crate::MResult<Vec<crate::IValue>> {
let reader =
self.sequential_reader(offset, std::mem::size_of::<$ty>() * elements_count)?;
let mut result = Vec::with_capacity(elements_count);
for _ in 0..elements_count {
let value = paste::paste! { reader.[<read_ $ty>]()};
result.push(IValue::$ity(value));
}
Ok(result)
}
};
}

View File

@ -15,6 +15,8 @@
*/
use crate::error::MemoryAccessError;
use crate::read_array_ty;
use crate::read_ty;
use crate::IValue;
use crate::MResult;
@ -25,98 +27,13 @@ pub struct MemoryReader<'m> {
}
/// Reads values of basic types sequentially from the provided reader.
/// It don't check memory limits for the optimization purposes,
/// so it could created by the MemoryReader::sequential_reader method.
/// It doesn't check memory limits for the optimization purposes,
/// so it could be created only by the MemoryReader::sequential_reader method.
pub struct SequentialReader<'r, 'm> {
reader: &'r MemoryReader<'m>,
offset: Cell<usize>,
}
macro_rules! value_der {
($self:expr, $offset:expr, @seq_start $($ids:tt),* @seq_end) => {
[$($self.reader.memory[$offset + $ids].get()),+]
};
($self:expr, $offset:expr, 1) => {
value_der!($self, $offset, @seq_start 0 @seq_end);
};
($self:expr, $offset:expr, 2) => {
value_der!($self, $offset, @seq_start 0, 1 @seq_end);
};
($self:expr, $offset:expr, 4) => {
value_der!($self, $offset, @seq_start 0, 1, 2, 3 @seq_end);
};
($self:expr, $offset:expr, 8) => {
value_der!($self, $offset, @seq_start 0, 1, 2, 3, 4, 5, 6, 7 @seq_end);
};
}
macro_rules! read_ty {
($func_name:ident, $ty:ty, 1) => {
pub fn $func_name(&self) -> $ty {
let offset = self.offset.get();
let result = <$ty>::from_le_bytes(value_der!(self, offset, 1));
self.offset.set(offset + 1);
result
}
};
($func_name:ident, $ty:ty, 2) => {
pub fn $func_name(&self) -> $ty {
let offset = self.offset.get();
let result = <$ty>::from_le_bytes(value_der!(self, offset, 2));
self.offset.set(offset + 2);
result
}
};
($func_name:ident, $ty:ty, 4) => {
pub fn $func_name(&self) -> $ty {
let offset = self.offset.get();
let result = <$ty>::from_le_bytes(value_der!(self, offset, 4));
self.offset.set(offset + 4);
result
}
};
($func_name:ident, $ty:ty, 8) => {
pub fn $func_name(&self) -> $ty {
let offset = self.offset.get();
let result = <$ty>::from_le_bytes(value_der!(self, offset, 8));
self.offset.set(offset + 8);
result
}
};
}
macro_rules! read_array_ty {
($func_name:ident, $ty:ident, $ity:ident) => {
pub fn $func_name(
&self,
offset: usize,
elements_count: usize,
) -> crate::MResult<Vec<crate::IValue>> {
let reader =
self.sequential_reader(offset, std::mem::size_of::<$ty>() * elements_count)?;
let mut result = Vec::with_capacity(elements_count);
for _ in 0..elements_count {
let value = paste::paste! { reader.[<read_ $ty>]()};
result.push(IValue::$ity(value));
}
Ok(result)
}
};
}
impl<'m> MemoryReader<'m> {
pub fn new(memory: &'m [Cell<u8>]) -> Self {
Self { memory }
@ -161,6 +78,8 @@ impl<'m> MemoryReader<'m> {
pub fn check_access(&self, offset: usize, size: usize) -> MResult<()> {
let right = offset + size;
// the first condition is a check for overflow
if right < offset || right >= self.memory.len() {
return Err(MemoryAccessError::InvalidAccess {
offset,

View File

@ -25,7 +25,7 @@ pub struct MemoryWriter<'m> {
/// Writes values of basic types sequentially to the provided writer.
/// It don't check memory limits for the optimization purposes,
/// so it could created by the MemoryReader::sequential_reader method.
/// so it could be created only by the MemoryReader::sequential_reader method.
pub struct SequentialWriter<'w, 'm> {
writer: &'w MemoryWriter<'m>,
offset: Cell<usize>,
@ -87,6 +87,8 @@ impl<'m> MemoryWriter<'m> {
pub fn check_access(&self, offset: usize, size: usize) -> MResult<()> {
let right = offset + size;
// the first condition is a check for overflow
if right < offset || right >= self.memory.len() {
return Err(MemoryAccessError::InvalidAccess {
offset,