mirror of
https://github.com/fluencelabs/interface-types
synced 2025-06-21 02:31:36 +00:00
refactoring
This commit is contained in:
@ -14,90 +14,23 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
pub mod error;
|
||||
mod macros;
|
||||
pub mod memory_reader;
|
||||
pub mod memory_writer;
|
||||
#![deny(
|
||||
dead_code,
|
||||
nonstandard_style,
|
||||
unused_imports,
|
||||
unused_mut,
|
||||
unused_variables,
|
||||
unused_unsafe,
|
||||
unreachable_patterns
|
||||
)]
|
||||
#![warn(rust_2018_idioms)]
|
||||
|
||||
pub mod lifter;
|
||||
pub mod lowerer;
|
||||
pub mod traits;
|
||||
pub mod utils;
|
||||
|
||||
pub use fluence_it_types::ne_vec::NEVec;
|
||||
pub use fluence_it_types::IRecordType;
|
||||
pub use fluence_it_types::IType;
|
||||
pub use fluence_it_types::IValue;
|
||||
|
||||
pub type ReadResult<T> = std::result::Result<T, error::MemoryAccessError>;
|
||||
pub type WriteResult<T> = std::result::Result<T, error::MemoryWriteError>;
|
||||
|
||||
/// Size of a value in a serialized view.
|
||||
pub fn ser_type_size(ty: &IType) -> usize {
|
||||
const WASM_POINTER_SIZE: usize = 4;
|
||||
|
||||
match ty {
|
||||
IType::Boolean | IType::S8 | IType::U8 => 1,
|
||||
IType::S16 | IType::U16 => 2,
|
||||
IType::S32 | IType::U32 | IType::I32 | IType::F32 => 4,
|
||||
IType::Record(_) => 4,
|
||||
// Vec-like types are passed by pointer and size
|
||||
IType::String | IType::ByteArray | IType::Array(_) => 2 * WASM_POINTER_SIZE,
|
||||
IType::S64 | IType::U64 | IType::I64 | IType::F64 => 8,
|
||||
}
|
||||
}
|
||||
|
||||
/// Size of a value in a serialized view.
|
||||
pub fn ser_value_size(value: &IValue) -> u32 {
|
||||
match value {
|
||||
IValue::Boolean(_) | IValue::S8(_) | IValue::U8(_) => 1,
|
||||
IValue::S16(_) | IValue::U16(_) => 2,
|
||||
IValue::S32(_) | IValue::U32(_) | IValue::F32(_) | IValue::I32(_) => 4,
|
||||
IValue::S64(_) | IValue::U64(_) | IValue::F64(_) | IValue::I64(_) => 8,
|
||||
IValue::String(_) | IValue::ByteArray(_) | IValue::Array(_) => 2 * 4,
|
||||
IValue::Record(_) => 4,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the record size in bytes.
|
||||
pub fn record_size(record_type: &IRecordType) -> usize {
|
||||
record_type
|
||||
.fields
|
||||
.iter()
|
||||
.map(|f| ser_type_size(&f.ty))
|
||||
.sum()
|
||||
}
|
||||
|
||||
pub fn type_tag_form_itype(itype: &IType) -> u32 {
|
||||
const POINTER_CODE: u32 = 3; // u32 in the sdk
|
||||
|
||||
match itype {
|
||||
IType::Boolean => 0, // u8
|
||||
IType::U8 => 1, // u8
|
||||
IType::U16 => 2, // u16
|
||||
IType::U32 => 3, // u32
|
||||
IType::U64 => 4, // u64
|
||||
IType::S8 => 6, // i8
|
||||
IType::S16 => 7, // i16
|
||||
IType::S32 | IType::I32 => 8, // i32
|
||||
IType::S64 | IType::I64 => 9, // i64
|
||||
IType::F32 => 10, // f32
|
||||
IType::F64 => 11, // f64
|
||||
IType::ByteArray | IType::Array(_) | IType::Record(_) | IType::String => POINTER_CODE,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn type_tag_form_ivalue(itype: &IValue) -> u32 {
|
||||
const POINTER_CODE: u32 = 3; // u32 in the sdk
|
||||
|
||||
match itype {
|
||||
IValue::Boolean(_) => 0, // u8
|
||||
IValue::U8(_) => 1, // u8
|
||||
IValue::U16(_) => 2, // u16
|
||||
IValue::U32(_) => 3, // u32
|
||||
IValue::U64(_) => 4, // u64
|
||||
IValue::S8(_) => 6, // i8
|
||||
IValue::S16(_) => 7, // i16
|
||||
IValue::S32(_) | IValue::I32(_) => 8, // i32
|
||||
IValue::S64(_) | IValue::I64(_) => 9, // i64
|
||||
IValue::F32(_) => 10, // f32
|
||||
IValue::F64(_) => 11, // f64
|
||||
IValue::ByteArray(_) | IValue::Array(_) | IValue::Record(_) | IValue::String(_) => {
|
||||
POINTER_CODE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
40
crates/it-lilo-utils/src/lifter/error.rs
Normal file
40
crates/it-lilo-utils/src/lifter/error.rs
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
use crate::traits::RecordResolvableError;
|
||||
use thiserror::Error as ThisError;
|
||||
|
||||
#[derive(Debug, ThisError)]
|
||||
pub enum LiError {
|
||||
#[error(
|
||||
"Out-of-bound Wasm memory access: offset {offset}, size {size}, while memory_size {memory_size}"
|
||||
)]
|
||||
InvalidAccess {
|
||||
offset: usize,
|
||||
size: usize,
|
||||
memory_size: usize,
|
||||
},
|
||||
|
||||
#[error("{0}")]
|
||||
RecordResolvableError(#[from] RecordResolvableError),
|
||||
|
||||
#[error("{0}")]
|
||||
InvalidUTF8String(#[from] std::string::FromUtf8Error),
|
||||
|
||||
/// This error occurred when a record is created from empty values array.
|
||||
#[error("Record with name '{0}' can't be empty")]
|
||||
EmptyRecord(String),
|
||||
}
|
126
crates/it-lilo-utils/src/lifter/lift_array.rs
Normal file
126
crates/it-lilo-utils/src/lifter/lift_array.rs
Normal file
@ -0,0 +1,126 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
use super::record_lift_memory;
|
||||
use super::ILifter;
|
||||
use super::LiResult;
|
||||
use crate::traits::RecordResolvable;
|
||||
use crate::utils::ser_type_size;
|
||||
use crate::IType;
|
||||
use crate::IValue;
|
||||
|
||||
pub fn array_lift_memory<R: RecordResolvable>(
|
||||
lifter: &ILifter<'_, '_, R>,
|
||||
value_type: &IType,
|
||||
offset: usize,
|
||||
elements_count: usize,
|
||||
) -> LiResult<IValue> {
|
||||
if elements_count == 0 {
|
||||
return Ok(IValue::Array(vec![]));
|
||||
}
|
||||
|
||||
let reader = &lifter.reader;
|
||||
|
||||
let ivalues = match value_type {
|
||||
IType::Boolean => reader.read_bool_array(offset, elements_count)?,
|
||||
IType::S8 => reader.read_s8_array(offset, elements_count)?,
|
||||
IType::S16 => reader.read_s16_array(offset, elements_count)?,
|
||||
IType::S32 => reader.read_s32_array(offset, elements_count)?,
|
||||
IType::S64 => reader.read_s64_array(offset, elements_count)?,
|
||||
IType::I32 => reader.read_i32_array(offset, elements_count)?,
|
||||
IType::I64 => reader.read_i64_array(offset, elements_count)?,
|
||||
IType::U8 => reader.read_u8_array(offset, elements_count)?,
|
||||
IType::U16 => reader.read_u16_array(offset, elements_count)?,
|
||||
IType::U32 => reader.read_u32_array(offset, elements_count)?,
|
||||
IType::U64 => reader.read_u64_array(offset, elements_count)?,
|
||||
IType::F32 => reader.read_f32_array(offset, elements_count)?,
|
||||
IType::F64 => reader.read_f64_array(offset, elements_count)?,
|
||||
IType::String => read_string_array(lifter, offset, elements_count)?,
|
||||
IType::ByteArray => read_array_array(lifter, &IType::ByteArray, offset, elements_count)?,
|
||||
IType::Array(ty) => read_array_array(lifter, &ty, offset, elements_count)?,
|
||||
IType::Record(record_type_id) => {
|
||||
read_record_array(lifter, *record_type_id, offset, elements_count)?
|
||||
}
|
||||
};
|
||||
|
||||
Ok(IValue::Array(ivalues))
|
||||
}
|
||||
|
||||
fn read_string_array<R: RecordResolvable>(
|
||||
lifter: &ILifter<'_, '_, R>,
|
||||
offset: usize,
|
||||
elements_count: usize,
|
||||
) -> LiResult<Vec<IValue>> {
|
||||
let mut result = Vec::with_capacity(elements_count);
|
||||
let seq_reader = lifter
|
||||
.reader
|
||||
.sequential_reader(offset, ser_type_size(&IType::String) * elements_count)?;
|
||||
|
||||
for _ in 0..elements_count {
|
||||
let offset = seq_reader.read_u32();
|
||||
let size = seq_reader.read_u32();
|
||||
|
||||
let raw_str = lifter.reader.read_raw_u8_array(offset as _, size as _)?;
|
||||
let str = String::from_utf8(raw_str)?;
|
||||
result.push(IValue::String(str));
|
||||
}
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
fn read_array_array<R: RecordResolvable>(
|
||||
lifter: &ILifter<'_, '_, R>,
|
||||
ty: &IType,
|
||||
offset: usize,
|
||||
elements_count: usize,
|
||||
) -> LiResult<Vec<IValue>> {
|
||||
let mut result = Vec::with_capacity(elements_count);
|
||||
let seq_reader = lifter
|
||||
.reader
|
||||
.sequential_reader(offset, ser_type_size(ty) * elements_count)?;
|
||||
|
||||
for _ in 0..elements_count {
|
||||
let offset = seq_reader.read_u32();
|
||||
let size = seq_reader.read_u32();
|
||||
|
||||
let array = array_lift_memory(lifter, ty, offset as _, size as _)?;
|
||||
result.push(array);
|
||||
}
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
fn read_record_array<R: RecordResolvable>(
|
||||
lifter: &ILifter<'_, '_, R>,
|
||||
record_type_id: u64,
|
||||
offset: usize,
|
||||
elements_count: usize,
|
||||
) -> LiResult<Vec<IValue>> {
|
||||
let mut result = Vec::with_capacity(elements_count);
|
||||
let seq_reader = lifter
|
||||
.reader
|
||||
.sequential_reader(offset, ser_type_size(&IType::Record(0)) * elements_count)?;
|
||||
|
||||
for _ in 0..elements_count {
|
||||
let offset = seq_reader.read_u32();
|
||||
let record_ty = lifter.resolver.resolve_record(record_type_id)?;
|
||||
|
||||
let record = record_lift_memory(lifter, &record_ty, offset as _)?;
|
||||
result.push(record);
|
||||
}
|
||||
|
||||
Ok(result)
|
||||
}
|
116
crates/it-lilo-utils/src/lifter/lift_record.rs
Normal file
116
crates/it-lilo-utils/src/lifter/lift_record.rs
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
use super::ILifter;
|
||||
use super::LiError;
|
||||
use super::LiResult;
|
||||
use super::MemoryReader;
|
||||
use super::SequentialReader;
|
||||
use crate::traits::RecordResolvable;
|
||||
use crate::utils::record_size;
|
||||
use crate::IRecordType;
|
||||
use crate::IType;
|
||||
use crate::IValue;
|
||||
use crate::NEVec;
|
||||
|
||||
pub fn record_lift_memory<R: RecordResolvable>(
|
||||
lifter: &ILifter<'_, '_, R>,
|
||||
record_type: &IRecordType,
|
||||
offset: usize,
|
||||
) -> LiResult<IValue> {
|
||||
let mut values = Vec::with_capacity(record_type.fields.len());
|
||||
|
||||
let size = record_size(record_type);
|
||||
let reader = &lifter.reader;
|
||||
let seq_reader = reader.sequential_reader(offset, size)?;
|
||||
|
||||
for field in (*record_type.fields).iter() {
|
||||
match &field.ty {
|
||||
IType::Boolean => values.push(IValue::Boolean(seq_reader.read_u8() != 0)),
|
||||
IType::S8 => values.push(IValue::S8(seq_reader.read_i8())),
|
||||
IType::S16 => values.push(IValue::S16(seq_reader.read_i16())),
|
||||
IType::S32 => values.push(IValue::S32(seq_reader.read_i32())),
|
||||
IType::S64 => values.push(IValue::S64(seq_reader.read_i64())),
|
||||
IType::I32 => values.push(IValue::I32(seq_reader.read_i32())),
|
||||
IType::I64 => values.push(IValue::I64(seq_reader.read_i64())),
|
||||
IType::U8 => values.push(IValue::U8(seq_reader.read_u8())),
|
||||
IType::U16 => values.push(IValue::U16(seq_reader.read_u16())),
|
||||
IType::U32 => values.push(IValue::U32(seq_reader.read_u32())),
|
||||
IType::U64 => values.push(IValue::U64(seq_reader.read_u64())),
|
||||
IType::F32 => values.push(IValue::F32(seq_reader.read_f32())),
|
||||
IType::F64 => values.push(IValue::F64(seq_reader.read_f64())),
|
||||
IType::String => values.push(IValue::String(read_string(reader, &seq_reader)?)),
|
||||
IType::ByteArray => values.push(read_byte_array(reader, &seq_reader)?),
|
||||
IType::Array(ty) => values.push(read_array(&lifter, &seq_reader, &**ty)?),
|
||||
IType::Record(record_type_id) => {
|
||||
values.push(read_record(lifter, &seq_reader, *record_type_id)?)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let record = NEVec::new(values.into_iter().collect())
|
||||
.map_err(|_| LiError::EmptyRecord(record_type.name.clone()))?;
|
||||
|
||||
Ok(IValue::Record(record))
|
||||
}
|
||||
|
||||
fn read_string(
|
||||
reader: &MemoryReader<'_>,
|
||||
seq_reader: &SequentialReader<'_, '_>,
|
||||
) -> LiResult<String> {
|
||||
let offset = seq_reader.read_u32();
|
||||
let size = seq_reader.read_u32();
|
||||
|
||||
let string_mem = reader.read_raw_u8_array(offset as _, size as _)?;
|
||||
|
||||
let string = String::from_utf8(string_mem)?;
|
||||
Ok(string)
|
||||
}
|
||||
|
||||
fn read_byte_array(
|
||||
reader: &MemoryReader<'_>,
|
||||
seq_reader: &SequentialReader<'_, '_>,
|
||||
) -> LiResult<IValue> {
|
||||
let offset = seq_reader.read_u32();
|
||||
let size = seq_reader.read_u32();
|
||||
|
||||
let array = reader.read_raw_u8_array(offset as _, size as _)?;
|
||||
|
||||
Ok(IValue::ByteArray(array))
|
||||
}
|
||||
|
||||
fn read_array<R: RecordResolvable>(
|
||||
lifter: &ILifter<'_, '_, R>,
|
||||
seq_reader: &SequentialReader<'_, '_>,
|
||||
value_type: &IType,
|
||||
) -> LiResult<IValue> {
|
||||
let offset = seq_reader.read_u32();
|
||||
let size = seq_reader.read_u32();
|
||||
|
||||
super::array_lift_memory(lifter, value_type, offset as _, size as _)
|
||||
}
|
||||
|
||||
fn read_record<R: RecordResolvable>(
|
||||
lifter: &ILifter<'_, '_, R>,
|
||||
seq_reader: &SequentialReader<'_, '_>,
|
||||
record_type_id: u64,
|
||||
) -> LiResult<IValue> {
|
||||
let offset = seq_reader.read_u32();
|
||||
|
||||
let record_type = lifter.resolver.resolve_record(record_type_id)?;
|
||||
|
||||
record_lift_memory(lifter, &record_type, offset as _)
|
||||
}
|
@ -101,7 +101,7 @@ macro_rules! read_array_ty {
|
||||
&self,
|
||||
offset: usize,
|
||||
elements_count: usize,
|
||||
) -> crate::ReadResult<Vec<crate::IValue>> {
|
||||
) -> super::LiResult<Vec<crate::IValue>> {
|
||||
let reader =
|
||||
self.sequential_reader(offset, std::mem::size_of::<$ty>() * elements_count)?;
|
||||
let mut result = Vec::with_capacity(elements_count);
|
@ -14,11 +14,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use crate::error::MemoryAccessError;
|
||||
use super::LiError;
|
||||
use super::LiResult;
|
||||
use crate::read_array_ty;
|
||||
use crate::read_ty;
|
||||
use crate::IValue;
|
||||
use crate::ReadResult;
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
@ -46,13 +46,13 @@ impl<'m> MemoryReader<'m> {
|
||||
&self,
|
||||
offset: usize,
|
||||
size: usize,
|
||||
) -> ReadResult<SequentialReader<'_, '_>> {
|
||||
) -> LiResult<SequentialReader<'_, '_>> {
|
||||
self.check_access(offset, size)?;
|
||||
|
||||
Ok(SequentialReader::new(&self, offset))
|
||||
}
|
||||
|
||||
pub fn read_raw_u8_array(&self, offset: usize, elements_count: usize) -> ReadResult<Vec<u8>> {
|
||||
pub fn read_raw_u8_array(&self, offset: usize, elements_count: usize) -> LiResult<Vec<u8>> {
|
||||
let reader = self.sequential_reader(offset, elements_count)?;
|
||||
let mut result = Vec::with_capacity(elements_count);
|
||||
|
||||
@ -64,7 +64,7 @@ impl<'m> MemoryReader<'m> {
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub fn read_bool_array(&self, offset: usize, elements_count: usize) -> ReadResult<Vec<IValue>> {
|
||||
pub fn read_bool_array(&self, offset: usize, elements_count: usize) -> LiResult<Vec<IValue>> {
|
||||
let reader = self.sequential_reader(offset, elements_count)?;
|
||||
let mut result = Vec::with_capacity(elements_count);
|
||||
|
||||
@ -76,12 +76,12 @@ impl<'m> MemoryReader<'m> {
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub fn check_access(&self, offset: usize, size: usize) -> ReadResult<()> {
|
||||
pub fn check_access(&self, offset: usize, size: usize) -> LiResult<()> {
|
||||
let right = offset + size;
|
||||
|
||||
// the first condition is a check for overflow
|
||||
if right < offset || right >= self.memory.len() {
|
||||
return Err(MemoryAccessError::InvalidAccess {
|
||||
return Err(LiError::InvalidAccess {
|
||||
offset,
|
||||
size,
|
||||
memory_size: self.memory.len(),
|
45
crates/it-lilo-utils/src/lifter/mod.rs
Normal file
45
crates/it-lilo-utils/src/lifter/mod.rs
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
mod error;
|
||||
mod lift_array;
|
||||
mod lift_record;
|
||||
mod macros;
|
||||
mod memory_reader;
|
||||
|
||||
pub use error::LiError;
|
||||
pub use lift_array::array_lift_memory;
|
||||
pub use lift_record::record_lift_memory;
|
||||
pub use memory_reader::MemoryReader;
|
||||
pub use memory_reader::SequentialReader;
|
||||
|
||||
use super::traits::RecordResolvable;
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
pub type LiResult<T> = std::result::Result<T, error::LiError>;
|
||||
|
||||
pub struct ILifter<'m, 'r, R: RecordResolvable> {
|
||||
pub reader: MemoryReader<'m>,
|
||||
pub resolver: &'r R,
|
||||
}
|
||||
|
||||
impl<'m, 'r, R: RecordResolvable> ILifter<'m, 'r, R> {
|
||||
pub fn new(memory: &'m [Cell<u8>], resolver: &'r R) -> Self {
|
||||
let reader = MemoryReader::new(memory);
|
||||
Self { reader, resolver }
|
||||
}
|
||||
}
|
28
crates/it-lilo-utils/src/lowerer/error.rs
Normal file
28
crates/it-lilo-utils/src/lowerer/error.rs
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
use crate::traits::AllocatableError;
|
||||
use crate::traits::RecordResolvableError;
|
||||
use thiserror::Error as ThisError;
|
||||
|
||||
#[derive(Debug, ThisError)]
|
||||
pub enum LoError {
|
||||
#[error("{0}")]
|
||||
AllocatableError(#[from] AllocatableError),
|
||||
|
||||
#[error("{0}")]
|
||||
RecordResolvableError(#[from] RecordResolvableError),
|
||||
}
|
96
crates/it-lilo-utils/src/lowerer/lower_array.rs
Normal file
96
crates/it-lilo-utils/src/lowerer/lower_array.rs
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
use super::ILowerer;
|
||||
use super::LoResult;
|
||||
use crate::traits::Allocatable;
|
||||
use crate::utils::ser_value_size;
|
||||
use crate::utils::type_tag_form_ivalue;
|
||||
use crate::IValue;
|
||||
|
||||
pub struct LoweredArray {
|
||||
pub offset: usize,
|
||||
pub size: usize,
|
||||
}
|
||||
|
||||
impl LoweredArray {
|
||||
pub fn new(offset: usize, size: usize) -> Self {
|
||||
Self { offset, size }
|
||||
}
|
||||
|
||||
pub fn empty() -> Self {
|
||||
Self { offset: 0, size: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn array_lower_memory<A: Allocatable>(
|
||||
lowerer: &ILowerer<'_, A>,
|
||||
array_values: Vec<IValue>,
|
||||
) -> LoResult<LoweredArray> {
|
||||
if array_values.is_empty() {
|
||||
return Ok(LoweredArray::empty());
|
||||
}
|
||||
|
||||
let elements_count = array_values.len() as u32;
|
||||
let size = ser_value_size(&array_values[0]) * elements_count;
|
||||
let type_tag = type_tag_form_ivalue(&array_values[0]);
|
||||
let seq_writer = lowerer.writer.sequential_writer(size, type_tag)?;
|
||||
|
||||
// here it's known that all interface values have the same type
|
||||
for value in array_values {
|
||||
match value {
|
||||
IValue::Boolean(value) => seq_writer.write_u8(&lowerer.writer, value as _),
|
||||
IValue::S8(value) => seq_writer.write_u8(&lowerer.writer, value as _),
|
||||
IValue::S16(value) => seq_writer.write_array(&lowerer.writer, value.to_le_bytes()),
|
||||
IValue::S32(value) => seq_writer.write_array(&lowerer.writer, value.to_le_bytes()),
|
||||
IValue::S64(value) => seq_writer.write_array(&lowerer.writer, value.to_le_bytes()),
|
||||
IValue::U8(value) => seq_writer.write_array(&lowerer.writer, value.to_le_bytes()),
|
||||
IValue::U16(value) => seq_writer.write_array(&lowerer.writer, value.to_le_bytes()),
|
||||
IValue::U32(value) => seq_writer.write_array(&lowerer.writer, value.to_le_bytes()),
|
||||
IValue::U64(value) => seq_writer.write_array(&lowerer.writer, value.to_le_bytes()),
|
||||
IValue::I32(value) => seq_writer.write_array(&lowerer.writer, value.to_le_bytes()),
|
||||
IValue::I64(value) => seq_writer.write_array(&lowerer.writer, value.to_le_bytes()),
|
||||
IValue::F32(value) => seq_writer.write_array(&lowerer.writer, value.to_le_bytes()),
|
||||
IValue::F64(value) => seq_writer.write_array(&lowerer.writer, value.to_le_bytes()),
|
||||
IValue::String(value) => {
|
||||
let offset = lowerer.writer.write_bytes(value.as_bytes())? as u32;
|
||||
|
||||
seq_writer.write_array(&lowerer.writer, offset.to_le_bytes());
|
||||
seq_writer.write_array(&lowerer.writer, (value.len() as u32).to_le_bytes());
|
||||
}
|
||||
IValue::ByteArray(values) => {
|
||||
let offset = lowerer.writer.write_bytes(&values)? as u32;
|
||||
|
||||
seq_writer.write_array(&lowerer.writer, offset.to_le_bytes());
|
||||
seq_writer.write_array(&lowerer.writer, (values.len() as u32).to_le_bytes());
|
||||
}
|
||||
IValue::Array(values) => {
|
||||
let LoweredArray { offset, size } = array_lower_memory(lowerer, values)?;
|
||||
|
||||
seq_writer.write_array(&lowerer.writer, (offset as u32).to_le_bytes());
|
||||
seq_writer.write_array(&lowerer.writer, (size as u32).to_le_bytes());
|
||||
}
|
||||
IValue::Record(values) => {
|
||||
let offset = super::record_lower_memory(lowerer, values)? as u32;
|
||||
seq_writer.write_array(&lowerer.writer, offset.to_le_bytes());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let offset = seq_writer.start_offset();
|
||||
let lowered_array = LoweredArray::new(offset as _, elements_count as _);
|
||||
Ok(lowered_array)
|
||||
}
|
78
crates/it-lilo-utils/src/lowerer/lower_record.rs
Normal file
78
crates/it-lilo-utils/src/lowerer/lower_record.rs
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
use super::ILowerer;
|
||||
use super::LoResult;
|
||||
use super::LoweredArray;
|
||||
use crate::traits::Allocatable;
|
||||
use crate::IValue;
|
||||
use crate::NEVec;
|
||||
|
||||
pub fn record_lower_memory<A: Allocatable>(
|
||||
lowerer: &ILowerer<'_, A>,
|
||||
values: NEVec<IValue>,
|
||||
) -> LoResult<i32> {
|
||||
let average_field_size = 4;
|
||||
// TODO: avoid this additional allocation after fixing github.com/fluencelabs/fce/issues/77
|
||||
let mut result: Vec<u8> = Vec::with_capacity(average_field_size * values.len());
|
||||
|
||||
for value in values.into_vec() {
|
||||
match value {
|
||||
IValue::Boolean(value) => result.push(value as _),
|
||||
IValue::S8(value) => result.push(value as _),
|
||||
IValue::S16(value) => result.extend_from_slice(&value.to_le_bytes()),
|
||||
IValue::S32(value) => result.extend_from_slice(&value.to_le_bytes()),
|
||||
IValue::S64(value) => result.extend_from_slice(&value.to_le_bytes()),
|
||||
IValue::U8(value) => result.push(value),
|
||||
IValue::U16(value) => result.extend_from_slice(&value.to_le_bytes()),
|
||||
IValue::U32(value) => result.extend_from_slice(&value.to_le_bytes()),
|
||||
IValue::U64(value) => result.extend_from_slice(&value.to_le_bytes()),
|
||||
IValue::I32(value) => result.extend_from_slice(&value.to_le_bytes()),
|
||||
IValue::I64(value) => result.extend_from_slice(&value.to_le_bytes()),
|
||||
IValue::F32(value) => result.extend_from_slice(&value.to_le_bytes()),
|
||||
IValue::F64(value) => result.extend_from_slice(&value.to_le_bytes()),
|
||||
IValue::String(value) => {
|
||||
let offset = lowerer.writer.write_bytes(value.as_bytes())? as u32;
|
||||
|
||||
result.extend_from_slice(&offset.to_le_bytes());
|
||||
result.extend_from_slice(&(value.len() as u32).to_le_bytes());
|
||||
}
|
||||
IValue::ByteArray(value) => {
|
||||
let offset = lowerer.writer.write_bytes(&value)? as u32;
|
||||
|
||||
result.extend_from_slice(&offset.to_le_bytes());
|
||||
result.extend_from_slice(&(value.len() as u32).to_le_bytes());
|
||||
}
|
||||
|
||||
IValue::Array(values) => {
|
||||
let LoweredArray { offset, size } = super::array_lower_memory(lowerer, values)?;
|
||||
|
||||
result.extend_from_slice(&(offset as u32).to_le_bytes());
|
||||
result.extend_from_slice(&(size as u32).to_le_bytes());
|
||||
}
|
||||
|
||||
IValue::Record(values) => {
|
||||
let offset = record_lower_memory(lowerer, values)? as u32;
|
||||
|
||||
result.extend_from_slice(&offset.to_le_bytes());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let result_pointer = lowerer.writer.write_bytes(&result)?;
|
||||
|
||||
Ok(result_pointer as _)
|
||||
}
|
@ -14,21 +14,16 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use crate::WriteResult;
|
||||
use super::LoResult;
|
||||
use crate::traits::Allocatable;
|
||||
use crate::traits::MemSlice;
|
||||
use crate::traits::DEFAULT_MEMORY_INDEX;
|
||||
use crate::utils::type_tag_form_itype;
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
pub type MemSlice<'m> = &'m [Cell<u8>];
|
||||
|
||||
const MEMORY_INDEX: usize = 0;
|
||||
|
||||
pub trait Heapable {
|
||||
fn allocate(&self, size: u32, type_tag: u32) -> WriteResult<usize>;
|
||||
|
||||
fn memory_slice(&self, memory_index: usize) -> WriteResult<MemSlice<'_>>;
|
||||
}
|
||||
|
||||
pub struct MemoryWriter<'i, T: Heapable> {
|
||||
heap_manager: &'i T,
|
||||
pub struct MemoryWriter<'i, R: Allocatable> {
|
||||
heap_manager: &'i R,
|
||||
pub(self) memory: Cell<MemSlice<'i>>,
|
||||
}
|
||||
|
||||
@ -37,9 +32,9 @@ pub struct SequentialWriter {
|
||||
offset: Cell<usize>,
|
||||
}
|
||||
|
||||
impl<'i, T: Heapable> MemoryWriter<'i, T> {
|
||||
pub fn new(heap_manager: &'i T) -> WriteResult<Self> {
|
||||
let mem_slice = heap_manager.memory_slice(MEMORY_INDEX)?;
|
||||
impl<'i, A: Allocatable> MemoryWriter<'i, A> {
|
||||
pub fn new(heap_manager: &'i A) -> LoResult<Self> {
|
||||
let mem_slice = heap_manager.memory_slice(DEFAULT_MEMORY_INDEX)?;
|
||||
let memory = Cell::new(mem_slice);
|
||||
|
||||
let writer = Self {
|
||||
@ -49,17 +44,17 @@ impl<'i, T: Heapable> MemoryWriter<'i, T> {
|
||||
Ok(writer)
|
||||
}
|
||||
|
||||
pub fn write_bytes(&self, bytes: &[u8]) -> WriteResult<usize> {
|
||||
let byte_type_tag = crate::type_tag_form_itype(&crate::IType::U8);
|
||||
pub fn write_bytes(&self, bytes: &[u8]) -> LoResult<usize> {
|
||||
let byte_type_tag = type_tag_form_itype(&crate::IType::U8);
|
||||
let seq_writer = self.sequential_writer(bytes.len() as _, byte_type_tag)?;
|
||||
seq_writer.write_bytes(self, bytes);
|
||||
|
||||
Ok(seq_writer.start_offset())
|
||||
}
|
||||
|
||||
pub fn sequential_writer(&self, size: u32, type_tag: u32) -> WriteResult<SequentialWriter> {
|
||||
pub fn sequential_writer(&self, size: u32, type_tag: u32) -> LoResult<SequentialWriter> {
|
||||
let offset = self.heap_manager.allocate(size, type_tag)?;
|
||||
let new_mem_slice = self.heap_manager.memory_slice(MEMORY_INDEX)?;
|
||||
let new_mem_slice = self.heap_manager.memory_slice(DEFAULT_MEMORY_INDEX)?;
|
||||
self.memory.set(new_mem_slice);
|
||||
|
||||
Ok(SequentialWriter::new(offset))
|
||||
@ -78,9 +73,9 @@ impl SequentialWriter {
|
||||
self.start_offset
|
||||
}
|
||||
|
||||
pub fn write_array<T: Heapable, const N: usize>(
|
||||
pub fn write_array<A: Allocatable, const N: usize>(
|
||||
&self,
|
||||
writer: &MemoryWriter<T>,
|
||||
writer: &MemoryWriter<'_, A>,
|
||||
values: [u8; N],
|
||||
) {
|
||||
let offset = self.offset.get();
|
||||
@ -94,7 +89,7 @@ impl SequentialWriter {
|
||||
}
|
||||
|
||||
// specialization of write_array for u8
|
||||
pub fn write_u8<T: Heapable>(&self, writer: &MemoryWriter<T>, value: u8) {
|
||||
pub fn write_u8<A: Allocatable>(&self, writer: &MemoryWriter<'_, A>, value: u8) {
|
||||
let offset = self.offset.get();
|
||||
|
||||
writer.memory.get()[offset].set(value);
|
||||
@ -103,7 +98,7 @@ impl SequentialWriter {
|
||||
}
|
||||
|
||||
// specialization of write_array for u32
|
||||
pub fn write_u32<T: Heapable>(&self, writer: &MemoryWriter<T>, value: u32) {
|
||||
pub fn write_u32<A: Allocatable>(&self, writer: &MemoryWriter<'_, A>, value: u32) {
|
||||
let offset = self.offset.get();
|
||||
|
||||
let value = value.to_le_bytes();
|
||||
@ -118,7 +113,7 @@ impl SequentialWriter {
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn write_bytes<T: Heapable>(&self, writer: &MemoryWriter<T>, bytes: &[u8]) {
|
||||
pub fn write_bytes<A: Allocatable>(&self, writer: &MemoryWriter<'_, A>, bytes: &[u8]) {
|
||||
let offset = self.offset.get();
|
||||
|
||||
let memory = writer.memory.get();
|
43
crates/it-lilo-utils/src/lowerer/mod.rs
Normal file
43
crates/it-lilo-utils/src/lowerer/mod.rs
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
mod error;
|
||||
mod lower_array;
|
||||
mod lower_record;
|
||||
mod memory_writer;
|
||||
|
||||
use crate::lowerer::memory_writer::MemoryWriter;
|
||||
use crate::traits::Allocatable;
|
||||
|
||||
pub use error::LoError;
|
||||
pub use lower_array::array_lower_memory;
|
||||
pub use lower_array::LoweredArray;
|
||||
pub use lower_record::record_lower_memory;
|
||||
|
||||
pub type LoResult<T> = std::result::Result<T, error::LoError>;
|
||||
|
||||
pub struct ILowerer<'m, A: Allocatable> {
|
||||
pub writer: MemoryWriter<'m, A>,
|
||||
}
|
||||
|
||||
impl<'m, A: Allocatable> ILowerer<'m, A> {
|
||||
pub fn new(allocatable: &'m A) -> LoResult<Self> {
|
||||
let writer = MemoryWriter::new(allocatable)?;
|
||||
let lowerer = Self { writer };
|
||||
|
||||
Ok(lowerer)
|
||||
}
|
||||
}
|
@ -14,22 +14,21 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
use std::cell::Cell;
|
||||
use thiserror::Error as ThisError;
|
||||
|
||||
#[derive(Debug, ThisError)]
|
||||
pub enum MemoryAccessError {
|
||||
#[error(
|
||||
"Out-of-bound Wasm memory access: offset {offset}, size {size}, while memory_size {memory_size}"
|
||||
)]
|
||||
InvalidAccess {
|
||||
offset: usize,
|
||||
size: usize,
|
||||
memory_size: usize,
|
||||
},
|
||||
pub const DEFAULT_MEMORY_INDEX: usize = 0;
|
||||
|
||||
pub type MemSlice<'m> = &'m [Cell<u8>];
|
||||
|
||||
pub trait Allocatable {
|
||||
fn allocate(&self, size: u32, type_tag: u32) -> Result<usize, AllocatableError>;
|
||||
|
||||
fn memory_slice(&self, memory_index: usize) -> Result<MemSlice<'_>, AllocatableError>;
|
||||
}
|
||||
|
||||
#[derive(Debug, ThisError)]
|
||||
pub enum MemoryWriteError {
|
||||
pub enum AllocatableError {
|
||||
/// The memory doesn't exist.
|
||||
#[error("memory `{memory_index}` does not exist")]
|
||||
MemoryIsMissing {
|
||||
@ -61,4 +60,9 @@ pub enum MemoryWriteError {
|
||||
probably a Wasm module's built with unsupported sdk version"
|
||||
)]
|
||||
AllocateFuncIncompatibleOutput,
|
||||
|
||||
// TODO: make it generic in future.
|
||||
/// User defined error.
|
||||
#[error("{0}")]
|
||||
UserDefinedError(String),
|
||||
}
|
21
crates/it-lilo-utils/src/traits/mod.rs
Normal file
21
crates/it-lilo-utils/src/traits/mod.rs
Normal file
@ -0,0 +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.
|
||||
*/
|
||||
|
||||
mod heapable;
|
||||
mod record_resolvable;
|
||||
|
||||
pub use heapable::*;
|
||||
pub use record_resolvable::*;
|
29
crates/it-lilo-utils/src/traits/record_resolvable.rs
Normal file
29
crates/it-lilo-utils/src/traits/record_resolvable.rs
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
use crate::IRecordType;
|
||||
use thiserror::Error as ThisError;
|
||||
|
||||
pub trait RecordResolvable {
|
||||
fn resolve_record(&self, record_type_id: u64) -> Result<&IRecordType, RecordResolvableError>;
|
||||
}
|
||||
|
||||
#[derive(Debug, ThisError)]
|
||||
pub enum RecordResolvableError {
|
||||
/// Record for such type is wasn't found.
|
||||
#[error("Record with type id '{0}' not found")]
|
||||
RecordNotFound(u64),
|
||||
}
|
95
crates/it-lilo-utils/src/utils.rs
Normal file
95
crates/it-lilo-utils/src/utils.rs
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
use crate::IRecordType;
|
||||
use crate::IType;
|
||||
use crate::IValue;
|
||||
|
||||
/// Size of a value in a serialized view.
|
||||
pub fn ser_type_size(ty: &IType) -> usize {
|
||||
const WASM_POINTER_SIZE: usize = 4;
|
||||
|
||||
match ty {
|
||||
IType::Boolean | IType::S8 | IType::U8 => 1,
|
||||
IType::S16 | IType::U16 => 2,
|
||||
IType::S32 | IType::U32 | IType::I32 | IType::F32 => 4,
|
||||
IType::Record(_) => 4,
|
||||
// Vec-like types are passed by pointer and size
|
||||
IType::String | IType::ByteArray | IType::Array(_) => 2 * WASM_POINTER_SIZE,
|
||||
IType::S64 | IType::U64 | IType::I64 | IType::F64 => 8,
|
||||
}
|
||||
}
|
||||
|
||||
/// Size of a value in a serialized view.
|
||||
pub fn ser_value_size(value: &IValue) -> u32 {
|
||||
match value {
|
||||
IValue::Boolean(_) | IValue::S8(_) | IValue::U8(_) => 1,
|
||||
IValue::S16(_) | IValue::U16(_) => 2,
|
||||
IValue::S32(_) | IValue::U32(_) | IValue::F32(_) | IValue::I32(_) => 4,
|
||||
IValue::S64(_) | IValue::U64(_) | IValue::F64(_) | IValue::I64(_) => 8,
|
||||
IValue::String(_) | IValue::ByteArray(_) | IValue::Array(_) => 2 * 4,
|
||||
IValue::Record(_) => 4,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the record size in bytes.
|
||||
pub fn record_size(record_type: &IRecordType) -> usize {
|
||||
record_type
|
||||
.fields
|
||||
.iter()
|
||||
.map(|f| ser_type_size(&f.ty))
|
||||
.sum()
|
||||
}
|
||||
|
||||
pub fn type_tag_form_itype(itype: &IType) -> u32 {
|
||||
const POINTER_CODE: u32 = 3; // u32 in the sdk
|
||||
|
||||
match itype {
|
||||
IType::Boolean => 0, // u8
|
||||
IType::U8 => 1, // u8
|
||||
IType::U16 => 2, // u16
|
||||
IType::U32 => 3, // u32
|
||||
IType::U64 => 4, // u64
|
||||
IType::S8 => 6, // i8
|
||||
IType::S16 => 7, // i16
|
||||
IType::S32 | IType::I32 => 8, // i32
|
||||
IType::S64 | IType::I64 => 9, // i64
|
||||
IType::F32 => 10, // f32
|
||||
IType::F64 => 11, // f64
|
||||
IType::ByteArray | IType::Array(_) | IType::Record(_) | IType::String => POINTER_CODE,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn type_tag_form_ivalue(itype: &IValue) -> u32 {
|
||||
const POINTER_CODE: u32 = 3; // u32 in the sdk
|
||||
|
||||
match itype {
|
||||
IValue::Boolean(_) => 0, // u8
|
||||
IValue::U8(_) => 1, // u8
|
||||
IValue::U16(_) => 2, // u16
|
||||
IValue::U32(_) => 3, // u32
|
||||
IValue::U64(_) => 4, // u64
|
||||
IValue::S8(_) => 6, // i8
|
||||
IValue::S16(_) => 7, // i16
|
||||
IValue::S32(_) | IValue::I32(_) => 8, // i32
|
||||
IValue::S64(_) | IValue::I64(_) => 9, // i64
|
||||
IValue::F32(_) => 10, // f32
|
||||
IValue::F64(_) => 11, // f64
|
||||
IValue::ByteArray(_) | IValue::Array(_) | IValue::Record(_) | IValue::String(_) => {
|
||||
POINTER_CODE
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user