From d14cf2fd4a9e03b3a5e86bb2caaa71e0981d9267 Mon Sep 17 00:00:00 2001 From: mertwole Date: Mon, 2 Oct 2023 16:33:15 +0300 Subject: [PATCH] Implement --- utils/wasm-gen/src/generator/syscalls.rs | 76 +++- .../src/generator/syscalls/invocator.rs | 26 +- utils/wasm-instrument/src/syscalls.rs | 392 ++++++++++++++---- 3 files changed, 383 insertions(+), 111 deletions(-) diff --git a/utils/wasm-gen/src/generator/syscalls.rs b/utils/wasm-gen/src/generator/syscalls.rs index 9fe6f122b74..e85c5bba222 100644 --- a/utils/wasm-gen/src/generator/syscalls.rs +++ b/utils/wasm-gen/src/generator/syscalls.rs @@ -42,7 +42,7 @@ pub use additional_data::*; pub use imports::*; pub use invocator::*; -use gear_wasm_instrument::syscalls::{ParamType, SysCallName, SysCallSignature}; +use gear_wasm_instrument::syscalls::{ParamType, PtrInfo, PtrType, SysCallName, SysCallSignature}; /// Type of invocable sys-call. /// @@ -79,34 +79,64 @@ impl InvocableSysCall { InvocableSysCall::Loose(name) => name.signature(), InvocableSysCall::Precise(name) => match name { SysCallName::ReservationSend => SysCallSignature::gr([ - ParamType::Ptr(None), // Address of recipient and value (HashWithValue struct) - ParamType::Ptr(Some(2)), // Pointer to payload - ParamType::Size, // Size of the payload - ParamType::Delay, // Number of blocks to delay the sending for - ParamType::Gas, // Amount of gas to reserve - ParamType::Duration, // Duration of the reservation - ParamType::Ptr(None), // Address of error returned + // Address of recipient and value (HashWithValue struct) + ParamType::Ptr(PtrInfo::new_immutable(PtrType::HashWithValue)), + // Pointer to payload + ParamType::Ptr(PtrInfo::new_immutable(PtrType::BufferStart { + length_param_idx: 2, + })), + // Size of the payload + ParamType::Size, + // Number of blocks to delay the sending for + ParamType::Delay, + // Amount of gas to reserve + ParamType::Gas, + // Duration of the reservation + ParamType::Duration, + // Address of error returned + ParamType::Ptr(PtrInfo::new_mutable(PtrType::ErrorWithHash)), ]), SysCallName::ReservationReply => SysCallSignature::gr([ - ParamType::Ptr(None), // Address of value - ParamType::Ptr(Some(2)), // Pointer to payload - ParamType::Size, // Size of the payload - ParamType::Gas, // Amount of gas to reserve - ParamType::Duration, // Duration of the reservation - ParamType::Ptr(None), // Address of error returned + // Address of value + ParamType::Ptr(PtrInfo::new_immutable(PtrType::Value)), + // Pointer to payload + ParamType::Ptr(PtrInfo::new_immutable(PtrType::BufferStart { + length_param_idx: 2, + })), + // Size of the payload + ParamType::Size, + // Amount of gas to reserve + ParamType::Gas, + // Duration of the reservation + ParamType::Duration, + // Address of error returned + ParamType::Ptr(PtrInfo::new_mutable(PtrType::ErrorWithHash)), ]), SysCallName::SendCommit => SysCallSignature::gr([ - ParamType::Ptr(None), // Address of recipient and value (HashWithValue struct) - ParamType::Ptr(Some(2)), // Pointer to payload - ParamType::Size, // Size of the payload - ParamType::Delay, // Number of blocks to delay the sending for - ParamType::Ptr(None), // Address of error returned + // Address of recipient and value (HashWithValue struct) + ParamType::Ptr(PtrInfo::new_immutable(PtrType::HashWithValue)), + // Address of value + ParamType::Ptr(PtrInfo::new_immutable(PtrType::Value)), + // Pointer to payload + ParamType::Ptr(PtrInfo::new_immutable(PtrType::BufferStart { + length_param_idx: 2, + })), + // Size of the payload + ParamType::Size, + // Number of blocks to delay the sending for + ParamType::Delay, + // Address of error returned, `ErrorCode` here because underlying syscalls have different error types + ParamType::Ptr(PtrInfo::new_mutable(PtrType::ErrorCode)), ]), SysCallName::SendCommitWGas => SysCallSignature::gr([ - ParamType::Ptr(None), // Address of recipient and value (HashWithValue struct) - ParamType::Delay, // Number of blocks to delay the sending for - ParamType::Gas, // Amount of gas to reserve - ParamType::Ptr(None), // Address of error returned + // Address of recipient and value (HashWithValue struct) + ParamType::Ptr(PtrInfo::new_immutable(PtrType::HashWithValue)), + // Number of blocks to delay the sending for + ParamType::Delay, + // Amount of gas to reserve + ParamType::Gas, + // Address of error returned, `ErrorCode` here because underlying syscalls have different error types + ParamType::Ptr(PtrInfo::new_mutable(PtrType::ErrorCode)), ]), _ => unimplemented!(), }, diff --git a/utils/wasm-gen/src/generator/syscalls/invocator.rs b/utils/wasm-gen/src/generator/syscalls/invocator.rs index d479812b2f3..be68e480bf9 100644 --- a/utils/wasm-gen/src/generator/syscalls/invocator.rs +++ b/utils/wasm-gen/src/generator/syscalls/invocator.rs @@ -29,7 +29,7 @@ use crate::{ use arbitrary::{Result, Unstructured}; use gear_wasm_instrument::{ parity_wasm::elements::{BlockType, Instruction, Internal, ValueType}, - syscalls::{ParamType, SysCallName, SysCallSignature}, + syscalls::{ParamType, PtrInfo, PtrType, SysCallName, SysCallSignature}, }; use std::{ collections::{btree_map::Entry, BTreeMap, BinaryHeap}, @@ -64,16 +64,18 @@ pub(crate) fn process_sys_call_params( ParamType::Alloc => ProcessedSysCallParams::Alloc { allowed_values: params_config.get_rule(¶m), }, - ParamType::Ptr(maybe_idx) => maybe_idx - .map(|_| { - // skipping next as we don't need the following `Size` param, - // because it will be chosen in accordance to the wasm module - // memory pages config. - skip_next_param = true; - - ProcessedSysCallParams::MemoryArray - }) - .unwrap_or(ProcessedSysCallParams::MemoryPtrValue), + ParamType::Ptr(PtrInfo { + ty: PtrType::BufferStart { .. }, + .. + }) => { + // skipping next as we don't need the following `Size` param, + // because it will be chosen in accordance to the wasm module + // memory pages config. + skip_next_param = true; + + ProcessedSysCallParams::MemoryArray + } + ParamType::Ptr(_) => ProcessedSysCallParams::MemoryPtrValue, _ => ProcessedSysCallParams::Value { value_type: param.into(), allowed_values: params_config.get_rule(¶m), @@ -565,7 +567,7 @@ impl<'a, 'b> SysCallsInvocator<'a, 'b> { params .last() .expect("The last argument of fallible syscall must be pointer to error code"), - ParamType::Ptr(None) + ParamType::Ptr(_) )); assert_eq!(params.len(), param_setters.len()); diff --git a/utils/wasm-instrument/src/syscalls.rs b/utils/wasm-instrument/src/syscalls.rs index 444c6873386..6d1667a3002 100644 --- a/utils/wasm-instrument/src/syscalls.rs +++ b/utils/wasm-instrument/src/syscalls.rs @@ -240,89 +240,259 @@ impl SysCallName { match self { Self::Alloc => SysCallSignature::system([Alloc], [I32]), Self::Free => SysCallSignature::system([Free], [I32]), - Self::Debug => SysCallSignature::gr([Ptr(Some(1)), Size]), - Self::Panic => SysCallSignature::gr([Ptr(Some(1)), Size]), + Self::Debug => SysCallSignature::gr([ + Ptr(PtrInfo::new_immutable(PtrType::BufferStart { + length_param_idx: 1, + })), + Size, + ]), + Self::Panic => SysCallSignature::gr([ + Ptr(PtrInfo::new_immutable(PtrType::BufferStart { + length_param_idx: 1, + })), + Size, + ]), Self::OomPanic => SysCallSignature::gr([]), - Self::BlockHeight => SysCallSignature::gr([Ptr(None)]), - Self::BlockTimestamp => SysCallSignature::gr([Ptr(None)]), - Self::Exit => SysCallSignature::gr([Ptr(None)]), - Self::GasAvailable => SysCallSignature::gr([Ptr(None)]), - Self::PayProgramRent => SysCallSignature::gr([Ptr(None), Ptr(None)]), - Self::ProgramId => SysCallSignature::gr([Ptr(None)]), + Self::BlockHeight => { + SysCallSignature::gr([Ptr(PtrInfo::new_mutable(PtrType::BlockNumber))]) + } + Self::BlockTimestamp => { + SysCallSignature::gr([Ptr(PtrInfo::new_mutable(PtrType::BlockTimestamp))]) + } + Self::Exit => SysCallSignature::gr([Ptr(PtrInfo::new_immutable(PtrType::Hash))]), + Self::GasAvailable => SysCallSignature::gr([Ptr(PtrInfo::new_mutable(PtrType::Gas))]), + Self::PayProgramRent => SysCallSignature::gr([ + Ptr(PtrInfo::new_immutable(PtrType::HashWithValue)), + Ptr(PtrInfo::new_mutable(PtrType::ErrorWithBlockNumberAndValue)), + ]), + Self::ProgramId => SysCallSignature::gr([Ptr(PtrInfo::new_mutable(PtrType::Hash))]), Self::Leave => SysCallSignature::gr([]), - Self::ValueAvailable => SysCallSignature::gr([Ptr(None)]), + Self::ValueAvailable => { + SysCallSignature::gr([Ptr(PtrInfo::new_mutable(PtrType::Value))]) + } Self::Wait => SysCallSignature::gr([]), Self::WaitUpTo => SysCallSignature::gr([Duration]), Self::WaitFor => SysCallSignature::gr([Duration]), - Self::Wake => SysCallSignature::gr([Ptr(None), Delay, Ptr(None)]), - Self::ReplyCode => SysCallSignature::gr([Ptr(None)]), - Self::SignalCode => SysCallSignature::gr([Ptr(None)]), - Self::MessageId => SysCallSignature::gr([Ptr(None)]), - Self::Read => SysCallSignature::gr([MessagePosition, Size, Ptr(None), Ptr(None)]), - Self::Reply => SysCallSignature::gr([Ptr(Some(1)), Size, Ptr(None), Ptr(None)]), - Self::ReplyInput => SysCallSignature::gr([Size, Size, Ptr(None), Ptr(None)]), - Self::ReplyWGas => { - SysCallSignature::gr([Ptr(Some(1)), Size, Gas, Ptr(None), Ptr(None)]) - } - Self::ReplyInputWGas => SysCallSignature::gr([Size, Size, Gas, Ptr(None), Ptr(None)]), - Self::ReplyCommit => SysCallSignature::gr([Ptr(None), Ptr(None)]), - Self::ReplyCommitWGas => SysCallSignature::gr([Gas, Ptr(None), Ptr(None)]), - Self::ReservationReply => { - SysCallSignature::gr([Ptr(None), Ptr(Some(2)), Size, Ptr(None)]) + Self::Wake => SysCallSignature::gr([ + Ptr(PtrInfo::new_immutable(PtrType::Hash)), + Delay, + Ptr(PtrInfo::new_mutable(PtrType::ErrorCode)), + ]), + Self::ReplyCode => { + SysCallSignature::gr([Ptr(PtrInfo::new_mutable(PtrType::ErrorWithReplyCode))]) } - Self::ReservationReplyCommit => SysCallSignature::gr([Ptr(None), Ptr(None)]), - Self::ReplyPush => SysCallSignature::gr([Ptr(Some(1)), Size, Ptr(None)]), - Self::ReplyPushInput => SysCallSignature::gr([Size, Size, Ptr(None)]), - Self::ReplyTo => SysCallSignature::gr([Ptr(None)]), - Self::SignalFrom => SysCallSignature::gr([Ptr(None)]), - Self::Send => SysCallSignature::gr([Ptr(None), Ptr(Some(2)), Size, Delay, Ptr(None)]), - Self::SendInput => SysCallSignature::gr([Ptr(None), Size, Size, Delay, Ptr(None)]), - Self::SendWGas => { - SysCallSignature::gr([Ptr(None), Ptr(Some(2)), Size, Gas, Delay, Ptr(None)]) + Self::SignalCode => { + SysCallSignature::gr([Ptr(PtrInfo::new_mutable(PtrType::ErrorWithSignalCode))]) } - Self::SendInputWGas => { - SysCallSignature::gr([Ptr(None), Size, Size, Gas, Delay, Ptr(None)]) + Self::MessageId => SysCallSignature::gr([Ptr(PtrInfo::new_mutable(PtrType::Hash))]), + Self::Read => SysCallSignature::gr([ + MessagePosition, + Size, + // TODO #3375, the PtrType::BlockNumber is incorrect here. + // Should be: + // Ptr(PtrInfo::new_mutable(PtrType::BufferStart { + // length_param_idx: 1, + // })) + Ptr(PtrInfo::new_mutable(PtrType::BlockNumber)), + Ptr(PtrInfo::new_mutable(PtrType::ErrorCode)), + ]), + Self::Reply => SysCallSignature::gr([ + Ptr(PtrInfo::new_immutable(PtrType::BufferStart { + length_param_idx: 1, + })), + Size, + Ptr(PtrInfo::new_immutable(PtrType::Value)), + Ptr(PtrInfo::new_mutable(PtrType::ErrorWithHash)), + ]), + Self::ReplyInput => SysCallSignature::gr([ + Size, + Size, + Ptr(PtrInfo::new_immutable(PtrType::Value)), + Ptr(PtrInfo::new_mutable(PtrType::ErrorWithHash)), + ]), + Self::ReplyWGas => SysCallSignature::gr([ + Ptr(PtrInfo::new_immutable(PtrType::BufferStart { + length_param_idx: 1, + })), + Size, + Gas, + Ptr(PtrInfo::new_immutable(PtrType::Value)), + Ptr(PtrInfo::new_mutable(PtrType::ErrorWithHash)), + ]), + Self::ReplyInputWGas => SysCallSignature::gr([ + Size, + Size, + Gas, + Ptr(PtrInfo::new_immutable(PtrType::Value)), + Ptr(PtrInfo::new_mutable(PtrType::ErrorWithHash)), + ]), + Self::ReplyCommit => SysCallSignature::gr([ + Ptr(PtrInfo::new_immutable(PtrType::Value)), + Ptr(PtrInfo::new_mutable(PtrType::ErrorWithHash)), + ]), + Self::ReplyCommitWGas => SysCallSignature::gr([ + Gas, + Ptr(PtrInfo::new_immutable(PtrType::Value)), + Ptr(PtrInfo::new_mutable(PtrType::ErrorWithHash)), + ]), + Self::ReservationReply => SysCallSignature::gr([ + Ptr(PtrInfo::new_immutable(PtrType::HashWithValue)), + Ptr(PtrInfo::new_immutable(PtrType::BufferStart { + length_param_idx: 2, + })), + Size, + Ptr(PtrInfo::new_mutable(PtrType::ErrorWithHash)), + ]), + Self::ReservationReplyCommit => SysCallSignature::gr([ + Ptr(PtrInfo::new_immutable(PtrType::HashWithValue)), + Ptr(PtrInfo::new_mutable(PtrType::ErrorWithHash)), + ]), + Self::ReplyPush => SysCallSignature::gr([ + Ptr(PtrInfo::new_immutable(PtrType::BufferStart { + length_param_idx: 1, + })), + Size, + Ptr(PtrInfo::new_mutable(PtrType::ErrorCode)), + ]), + Self::ReplyPushInput => { + SysCallSignature::gr([Size, Size, Ptr(PtrInfo::new_mutable(PtrType::ErrorCode))]) } - Self::SendCommit => SysCallSignature::gr([Handler, Ptr(None), Delay, Ptr(None)]), - Self::SendCommitWGas => { - SysCallSignature::gr([Handler, Ptr(None), Gas, Delay, Ptr(None)]) + Self::ReplyTo => { + SysCallSignature::gr([Ptr(PtrInfo::new_mutable(PtrType::ErrorWithHash))]) } - Self::SendInit => SysCallSignature::gr([Ptr(None)]), - Self::SendPush => SysCallSignature::gr([Handler, Ptr(Some(2)), Size, Ptr(None)]), - Self::SendPushInput => SysCallSignature::gr([Handler, Size, Size, Ptr(None)]), - Self::ReservationSend => { - SysCallSignature::gr([Ptr(None), Ptr(Some(2)), Size, Delay, Ptr(None)]) + Self::SignalFrom => { + SysCallSignature::gr([Ptr(PtrInfo::new_mutable(PtrType::ErrorWithHash))]) } - Self::ReservationSendCommit => { - SysCallSignature::gr([Handler, Ptr(None), Delay, Ptr(None)]) + Self::Send => SysCallSignature::gr([ + Ptr(PtrInfo::new_immutable(PtrType::HashWithValue)), + Ptr(PtrInfo::new_immutable(PtrType::BufferStart { + length_param_idx: 2, + })), + Size, + Delay, + Ptr(PtrInfo::new_mutable(PtrType::ErrorWithHash)), + ]), + Self::SendInput => SysCallSignature::gr([ + Ptr(PtrInfo::new_immutable(PtrType::HashWithValue)), + Size, + Size, + Delay, + Ptr(PtrInfo::new_mutable(PtrType::ErrorWithHash)), + ]), + Self::SendWGas => SysCallSignature::gr([ + Ptr(PtrInfo::new_immutable(PtrType::HashWithValue)), + Ptr(PtrInfo::new_immutable(PtrType::BufferStart { + length_param_idx: 2, + })), + Size, + Gas, + Delay, + Ptr(PtrInfo::new_mutable(PtrType::ErrorWithHash)), + ]), + Self::SendInputWGas => SysCallSignature::gr([ + Ptr(PtrInfo::new_immutable(PtrType::HashWithValue)), + Size, + Size, + Gas, + Delay, + Ptr(PtrInfo::new_mutable(PtrType::ErrorWithHash)), + ]), + Self::SendCommit => SysCallSignature::gr([ + Handler, + Ptr(PtrInfo::new_immutable(PtrType::HashWithValue)), + Delay, + Ptr(PtrInfo::new_mutable(PtrType::ErrorWithHash)), + ]), + Self::SendCommitWGas => SysCallSignature::gr([ + Handler, + Ptr(PtrInfo::new_immutable(PtrType::HashWithValue)), + Gas, + Delay, + Ptr(PtrInfo::new_mutable(PtrType::ErrorWithHash)), + ]), + Self::SendInit => { + SysCallSignature::gr([Ptr(PtrInfo::new_mutable(PtrType::ErrorWithHandle))]) } - Self::Size => SysCallSignature::gr([Ptr(None)]), - Self::Source => SysCallSignature::gr([Ptr(None)]), - Self::Value => SysCallSignature::gr([Ptr(None)]), + Self::SendPush => SysCallSignature::gr([ + Handler, + Ptr(PtrInfo::new_immutable(PtrType::BufferStart { + length_param_idx: 2, + })), + Size, + Ptr(PtrInfo::new_mutable(PtrType::ErrorCode)), + ]), + Self::SendPushInput => SysCallSignature::gr([ + Handler, + Size, + Size, + Ptr(PtrInfo::new_mutable(PtrType::ErrorCode)), + ]), + Self::ReservationSend => SysCallSignature::gr([ + Ptr(PtrInfo::new_immutable(PtrType::TwoHashesWithValue)), + Ptr(PtrInfo::new_immutable(PtrType::BufferStart { + length_param_idx: 2, + })), + Size, + Delay, + Ptr(PtrInfo::new_mutable(PtrType::ErrorWithHash)), + ]), + Self::ReservationSendCommit => SysCallSignature::gr([ + Handler, + Ptr(PtrInfo::new_immutable(PtrType::TwoHashesWithValue)), + Delay, + Ptr(PtrInfo::new_mutable(PtrType::ErrorWithHash)), + ]), + Self::Size => SysCallSignature::gr([Ptr(PtrInfo::new_mutable(PtrType::Length))]), + Self::Source => SysCallSignature::gr([Ptr(PtrInfo::new_mutable(PtrType::Hash))]), + Self::Value => SysCallSignature::gr([Ptr(PtrInfo::new_mutable(PtrType::Value))]), Self::CreateProgram => SysCallSignature::gr([ - Ptr(None), - Ptr(Some(2)), + Ptr(PtrInfo::new_immutable(PtrType::HashWithValue)), + Ptr(PtrInfo::new_immutable(PtrType::BufferStart { + length_param_idx: 2, + })), Size, - Ptr(Some(4)), + Ptr(PtrInfo::new_immutable(PtrType::BufferStart { + length_param_idx: 4, + })), Size, Delay, - Ptr(None), + Ptr(PtrInfo::new_mutable(PtrType::ErrorWithTwoHashes)), ]), Self::CreateProgramWGas => SysCallSignature::gr([ - Ptr(None), - Ptr(Some(2)), + Ptr(PtrInfo::new_immutable(PtrType::HashWithValue)), + Ptr(PtrInfo::new_immutable(PtrType::BufferStart { + length_param_idx: 2, + })), Size, - Ptr(Some(4)), + Ptr(PtrInfo::new_immutable(PtrType::BufferStart { + length_param_idx: 4, + })), Size, Gas, Delay, - Ptr(None), + Ptr(PtrInfo::new_mutable(PtrType::ErrorWithTwoHashes)), + ]), + Self::ReplyDeposit => SysCallSignature::gr([ + Ptr(PtrInfo::new_immutable(PtrType::Hash)), + Gas, + Ptr(PtrInfo::new_mutable(PtrType::ErrorCode)), + ]), + Self::ReserveGas => SysCallSignature::gr([ + Gas, + Duration, + Ptr(PtrInfo::new_mutable(PtrType::ErrorWithHash)), + ]), + Self::UnreserveGas => SysCallSignature::gr([ + Ptr(PtrInfo::new_immutable(PtrType::Hash)), + Ptr(PtrInfo::new_mutable(PtrType::ErrorWithGas)), + ]), + Self::SystemReserveGas => { + SysCallSignature::gr([Gas, Ptr(PtrInfo::new_mutable(PtrType::ErrorCode))]) + } + Self::Random => SysCallSignature::gr([ + Ptr(PtrInfo::new_immutable(PtrType::Hash)), + Ptr(PtrInfo::new_mutable(PtrType::BlockNumberWithHash)), ]), - Self::ReplyDeposit => SysCallSignature::gr([Ptr(None), Gas, Ptr(None)]), - Self::ReserveGas => SysCallSignature::gr([Gas, Duration, Ptr(None)]), - Self::UnreserveGas => SysCallSignature::gr([Ptr(None), Ptr(None)]), - Self::SystemReserveGas => SysCallSignature::gr([Gas, Ptr(None)]), - Self::Random => SysCallSignature::gr([Ptr(None), Ptr(None)]), other => panic!("Unknown syscall: '{:?}'", other), } } @@ -343,23 +513,93 @@ impl SysCallName { /// Syscall param type. /// -/// `Ptr` is usually used to point to the beginning of the array in memory. -/// In order to distinguish between pointer to the memory array and pointer -/// to some value, `Ptr` was defined as a tuple-like struct that owns an -/// optional index of the memory array size parameter. So if current sys-call -/// doesn't accept any memory array as an argument, then pointer parameter will -/// be `Ptr(None)`. +/// `Ptr` variant contains additional data about the type this pointer +/// belongs to. See [`PtrInfo`] and [`PtrType`] for more details. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] pub enum ParamType { - Size, // i32 buffers size in memory - Ptr(Option), // i32 pointer - Gas, // i64 gas amount - MessagePosition, // i32 message position - Duration, // i32 duration in blocks - Delay, // i32 delay in blocks - Handler, // i32 handler number - Alloc, // i32 alloc pages - Free, // i32 free page + Size, // i32 buffers size in memory + Ptr(PtrInfo), // i32 pointer + Gas, // i64 gas amount + MessagePosition, // i32 message position + Duration, // i32 duration in blocks + Delay, // i32 delay in blocks + Handler, // i32 handler number + Alloc, // i32 alloc pages + Free, // i32 free page +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub struct PtrInfo { + pub mutable: bool, + pub ty: PtrType, +} + +impl PtrInfo { + pub fn new_immutable(ty: PtrType) -> PtrInfo { + PtrInfo { mutable: false, ty } + } + + pub fn new_mutable(ty: PtrType) -> PtrInfo { + PtrInfo { mutable: true, ty } + } +} + +/// Pointer type. +/// +/// Used to distinguish between different pointer types in the syscall signatures. +/// Basically it responds to different types from `gsys`. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] +pub enum PtrType { + BlockNumber, + BlockTimestamp, + BufferStart { length_param_idx: usize }, + Hash, + Gas, + Length, + Value, + + BlockNumberWithHash, + HashWithValue, + TwoHashes, + TwoHashesWithValue, + + ErrorCode, + + ErrorWithReplyCode, + ErrorWithSignalCode, + ErrorWithGas, + ErrorWithHandle, + ErrorWithHash, + ErrorWithTwoHashes, + ErrorWithBlockNumberAndValue, +} + +impl PtrType { + pub fn is_error(self) -> bool { + use PtrType::*; + + match self { + ErrorCode + | ErrorWithReplyCode + | ErrorWithSignalCode + | ErrorWithGas + | ErrorWithHandle + | ErrorWithHash + | ErrorWithTwoHashes + | ErrorWithBlockNumberAndValue => true, + BlockNumber + | BlockTimestamp + | BufferStart { .. } + | Hash + | Gas + | Length + | Value + | BlockNumberWithHash + | HashWithValue + | TwoHashes + | TwoHashesWithValue => false, + } + } } impl From for ValueType {