3#include <boost/preprocessor/seq/for_each.hpp>
4#include <boost/preprocessor/seq/subseq.hpp>
5#include <boost/preprocessor/seq/remove.hpp>
6#include <boost/preprocessor/seq/push_back.hpp>
16#include <unordered_map>
23namespace sysio {
namespace chain {
namespace wasm_ops {
31 if (
idx >= data.size())
32 data.resize(data.size()*2);
33 data[
idx++] =
static_cast<U8>(c);
35 void set(
size_t i,
const char* arr) {
36 if (i+
idx >= data.size())
37 data.resize(data.size()*2+i);
42 std::vector<U8>
get() {
86 return std::string(
"i32 : ")+std::to_string(
field);
89 return std::string(
"i64 : ")+std::to_string(
field);
92 return std::string(
"blocktype : ")+std::to_string((
uint32_t)
field.result);
95 return std::string(
"memoryoptype : ")+std::to_string((
uint32_t)
field.end);
98 return std::string(
"memarg : ")+std::to_string(
field.a)+std::string(
", ")+std::to_string(
field.o);
101 return std::string(
"branchtabletype : ")+std::to_string(
field.target_depth)+std::string(
", ")+std::to_string(
field.table_index);
106 stream->set(
sizeof(packed), packed);
111 stream->set(
sizeof(packed), packed);
114 const char packed[] = { char(
field.result) };
115 stream->set(
sizeof(packed), packed);
118 const char packed[] = { char(
field.end) };
119 stream->set(
sizeof(packed), packed);
122 const char packed[] = { char(
field.a), char(
field.a >> 8), char(
field.a >> 16), char(
field.a >> 24),
124 stream->set(
sizeof(packed), packed);
128 const char packed[] = { char(
field.target_depth), char(
field.target_depth >> 8), char(
field.target_depth >> 16), char(
field.target_depth >> 24),
129 char(
field.target_depth >> 32), char(
field.target_depth >> 40), char(
field.target_depth >> 48), char(
field.target_depth >> 56),
130 char(
field.table_index), char(
field.table_index >> 8), char(
field.table_index >> 16), char(
field.table_index >> 24),
131 char(
field.table_index >> 32), char(
field.table_index >> 40), char(
field.table_index >> 48), char(
field.table_index >> 56) };
132 stream->set(
sizeof(packed), packed);
135template <
typename Field>
138 static auto unpack(
char* opcode, Field&
f ) {
f = *
reinterpret_cast<Field*
>(opcode); }
151#define CONSTRUCT_OP_HAS_DATA( r, DATA, OP ) \
152template <typename ... Mutators> \
153struct OP final : instr_base<Mutators...> { \
154 uint16_t code = BOOST_PP_CAT(OP,_code); \
156 uint16_t get_code() override { return BOOST_PP_CAT(OP,_code); } \
157 int skip_ahead() override { return field_specific_params<DATA>::skip_ahead; } \
158 void unpack( char* opcode ) override { \
159 field_specific_params<DATA>::unpack( opcode, field ); \
161 void pack(instruction_stream* stream) override { \
162 stream->set(2, (const char*)&code); \
163 field_specific_params<DATA>::pack( stream, field ); \
165 std::string to_string() override { \
166 return std::string(BOOST_PP_STRINGIZE(OP))+field_specific_params<DATA>::to_string( field ); \
170#define WASM_OP_SEQ (error) \
287 (f32_convert_s_i32) \
288 (f32_convert_u_i32) \
289 (f32_convert_s_i64) \
290 (f32_convert_u_i64) \
292 (f64_convert_s_i32) \
293 (f64_convert_u_i32) \
294 (f64_convert_s_i64) \
295 (f64_convert_u_i64) \
297 (i32_reinterpret_f32) \
298 (i64_reinterpret_f64) \
299 (f32_reinterpret_i32) \
300 (f64_reinterpret_i64) \
544template <
typename Mutator,
typename ... Mutators>
548template <
typename Mutator>
550 static constexpr bool value = Mutator::kills;
552template <
typename Mutator,
typename ... Mutators>
556template <
typename Mutator>
558 static constexpr bool value = Mutator::post;
560template <
typename ... Mutators>
565 for (
auto m : { Mutators::accept... } ) {
578#undef CONSTRUCT_OP_HAS_DATA
583 static constexpr bool kills =
false;
584 static constexpr bool post =
false;
589template <
typename Mutator = nop_mutator,
typename ... Mutators>
591#define GEN_TYPE( r, T, OP ) \
592 using BOOST_PP_CAT( OP, _t ) = OP < T , BOOST_PP_CAT(T, s) ...>;
601template <
class Op_Types>
603#define GEN_FIELD( r, P, OP ) \
604 static std::unique_ptr<typename Op_Types::BOOST_PP_CAT(OP,_t)> BOOST_PP_CAT(P, OP);
608 static std::vector<instr*> _cached_ops;
611#define PUSH_BACK_OP( r, T, OP ) \
612 _cached_ops[BOOST_PP_CAT(OP,_code)] = BOOST_PP_CAT(T, OP).get();
613 if ( _cached_ops.empty() ) {
615 _cached_ops.resize( 256, cached_error.get() );
623template <
class Op_Types>
624std::vector<instr*> cached_ops<Op_Types>::_cached_ops;
626#define INIT_FIELD( r, P, OP ) \
627 template <class Op_Types> \
628 std::unique_ptr<typename Op_Types::BOOST_PP_CAT(OP,_t)> cached_ops<Op_Types>::BOOST_PP_CAT(P, OP) = std::make_unique<typename Op_Types::BOOST_PP_CAT(OP,_t)>();
631template <
class Op_Types>
633 #define GEN_FIELD( r, P, OP ) \
634 static std::unique_ptr<typename Op_Types::BOOST_PP_CAT(OP,_t)> BOOST_PP_CAT(P, OP) = std::make_unique<typename Op_Types::BOOST_PP_CAT(OP,_t)>();
637 static std::vector<instr*> _cached_ops;
639#define PUSH_BACK_OP( r, T, OP ) \
640 _cached_ops[BOOST_PP_CAT(OP,_code)] = BOOST_PP_CAT(T, OP).get();
642 if ( _cached_ops.empty() ) {
644 _cached_ops.resize( 256, cached_error.get() );
654template <
class Op_Types>
658 : start(codeBytes.data()), nextByte(codeBytes.data()), end(codeBytes.data()+codeBytes.size()) {
663 operator bool()
const {
return nextByte < end; }
670 #define VISIT_OPCODE(opcode,name,nameString,Imm,...) \
671 case IR::Opcode::name: \
673 SYS_ASSERT(nextByte + sizeof(IR::OpcodeAndImm<IR::Imm>) <= end, wasm_exception, ""); \
674 IR::OpcodeAndImm<IR::Imm>* encodedOperator = (IR::OpcodeAndImm<IR::Imm>*)nextByte; \
675 nextByte += sizeof(IR::OpcodeAndImm<IR::Imm>); \
676 auto op = _cached_ops->at(BOOST_PP_CAT(name, _code)); \
677 op->unpack( reinterpret_cast<char*>(&(encodedOperator->imm)) ); \
684 return _cached_ops->at(error_code);
689 const U8* savedNextByte = nextByte;
691 nextByte = savedNextByte;
697 static const std::vector<instr*>* _cached_ops;
703template <
class Op_Types>
704const std::vector<instr*>* SYSIO_OperatorDecoderStream<Op_Types>::_cached_ops;
#define ENUM_OPERATORS(visitOp)
#define SYS_ASSERT(expr, exc_type, FORMAT,...)
static std::vector< instr * > * get_cached_ops()
void operator<<(const char c)
instruction_stream(size_t size)
void set(size_t i, const char *arr)
Defines exception's used by fc.
VISIT_OPCODE(opcode, name,...)
std::unique_ptr< instr > wasm_op_ptr
void pack(instruction_stream *stream, uint32_t field)
std::vector< uint8_t >::iterator code_iterator
std::function< std::vector< wasm_instr_ptr >(uint8_t)> wasm_instr_callback
std::string to_string(uint32_t field)
std::vector< instr * > * get_cached_ops_vec()
std::function< wasm_instr_ptr(std::vector< uint8_t >, size_t)> wasm_op_generator
std::shared_ptr< instr > wasm_instr_ptr
std::vector< uint8_t > code_vector
std::vector< uint8_t > wasm_return_t
@ f64_reinterpret_i64_code
@ f32_reinterpret_i32_code
@ i64_reinterpret_f64_code
@ i32_reinterpret_f32_code
key Invalid authority Invalid transaction Invalid block ID Invalid packed transaction Invalid chain ID Invalid symbol Signature type is not a currently activated type Block can not be found Unlinkable block Block does not guarantee concurrent execution without conflicts Block exhausted allowed resources Block is from the future Block is not signed by expected producer Block includes an ill formed protocol feature activation extension Block includes an ill formed additional block signature extension Error decompressing transaction Transaction should have at least one required authority Expired Transaction Invalid Reference Block Duplicate deferred transaction The transaction can not be found Transaction is too big Invalid transaction extension Transaction includes disallowed Transaction exceeded transient resource limit Account name already exists sysio_assert_message assertion failure Action can not be found Attempt to use unaccessible API Inline Action exceeds maximum size limit sysio_assert_code assertion failure uses restricted error code value action return value size too big Permission Query Exception Contract Table Query Exception Database is an unknown or unsupported version Database usage is at unsafe levels wasm_exception
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
#define T(meth, val, expected)
#define FC_REFLECT_TEMPLATE(TEMPLATE_ARGS, TYPE, MEMBERS)
#define FC_REFLECT(TYPE, MEMBERS)
Specializes fc::reflector for TYPE.
unsigned __int64 uint64_t
instr * decodeOpWithoutConsume()
SYSIO_OperatorDecoderStream(const std::vector< U8 > &codeBytes)
static void pack(instruction_stream *stream, voidtype &f)
static auto unpack(char *opcode, voidtype &f)
static auto to_string(voidtype &f)
static void pack(instruction_stream *stream, Field &f)
static auto unpack(char *opcode, Field &f)
static auto to_string(Field &f)
static constexpr int skip_ahead
virtual void visit(visitor_arg &&arg) override
virtual std::string to_string()
virtual void pack(instruction_stream *stream)=0
virtual void visit(visitor_arg &&arg)=0
virtual uint16_t get_code()=0
virtual int skip_ahead()=0
virtual void unpack(char *opcode)=0
static constexpr bool post
static constexpr bool kills
static void accept(instr *inst, visitor_arg &arg)
static constexpr bool value
static constexpr bool value
IR::FunctionDef * function_def
instruction_stream * new_code
#define CONSTRUCT_OP_HAS_DATA(r, DATA, OP)
#define INIT_FIELD(r, P, OP)
#define GEN_FIELD(r, P, OP)
#define PUSH_BACK_OP(r, T, OP)
#define GEN_TYPE(r, T, OP)
memcpy((char *) pInfo->slotDescription, s, l)