3#include <sysio/vm/exceptions.hpp>
4#include <sysio/vm/guarded_ptr.hpp>
12namespace sysio {
namespace vm {
15 if constexpr (
N == 1 ||
N == 7)
17 else if constexpr (
N == 32)
26 static_assert(
N == 1 ||
N == 7 ||
N == 32,
"N not valid");
33 inline constexpr void from(
bool v) { storage[0] = v; }
35 storage[0] = v & 0x7f;
42#elif defined(__GNUC__)
45 for (; bytes_used < bytes_needed<N>(); bytes_used++) {
46 storage[bytes_used] = v & 0x7f;
49 storage[bytes_used] |= 0x80;
60 SYS_VM_ASSERT( code.offset()+cnt < code.bounds(), wasm_interpreter_exception,
"pointer out of bounds" );
61 storage[cnt] = code[cnt];
62 if ((storage[cnt] & 0x80) == 0) {
65 SYS_VM_ASSERT((mask & storage[cnt]) == 0, wasm_parse_exception,
"unused bits of unsigned leb128 must be 0");
74 size_t size()
const {
return bytes_used; }
76 template <
size_t M=N,
typename =
typename std::enable_if_t<M == 1,
int>>
77 inline constexpr bool to() {
return storage[0]; }
79 template <
size_t M=N,
typename =
typename std::enable_if_t<M == 7,
int>>
80 inline constexpr uint8_t to() {
return storage[0] & 0x7f; }
82 template <
size_t M=N,
typename =
typename std::enable_if_t<M == 32,
int>>
88#elif defined(__GNUC__)
91 for (
int i=bytes_used-1; i >= 0; i--) {
93 ret |= storage[i] & 0x7f;
99 for (
int i=0; i < bytes_used; i++) {
100 std::cout << std::hex <<
"0x" << (int)storage[i] <<
' ';
102 std::cout << std::endl;
106 std::array<uint8_t, bytes_needed<N>()> storage;
113 static_assert(
N == 7 ||
N == 32 ||
N == 64,
"N not valid");
121 static_assert(
N >= 7,
"cant use this constructor with N < 7");
122 storage[0] = v & 0x7f;
125 static_assert(
N >= 32,
"cant use this constructor with N < 32");
129 static_assert(
N >= 64,
"cant use this constructor with N < 32");
137 SYS_VM_ASSERT( code.offset()+cnt < code.bounds(), wasm_interpreter_exception,
"pointer out of bounds" );
138 storage[cnt] = code[cnt];
139 if ((storage[cnt] & 0x80) == 0) {
144 SYS_VM_ASSERT((mask & storage[cnt]) == expected, wasm_parse_exception,
"unused bits of signed leb128 must be the same as the sign bit");
153 size_t size()
const {
return bytes_used; }
155 template <
size_t M=N,
typename =
typename std::enable_if_t<M == 1,
int>>
156 inline constexpr bool to() {
return storage[0]; }
158 template <
size_t M=N,
typename =
typename std::enable_if_t<M == 7,
int>>
160 if (storage[0] & 0x40)
161 return storage[0] | (~0u << 7);
165 template <
size_t M=N,
typename =
typename std::enable_if_t<M == 32,
int>>
166 inline constexpr int32_t to() {
return _to<int32_t>(); }
168 template <
size_t M=N,
typename =
typename std::enable_if_t<M == 64,
int>>
169 inline constexpr int64_t to() {
return _to<int64_t>(); }
172 for (
int i=0; i < bytes_used; i++) {
173 std::cout << std::hex <<
"0x" << (int)storage[i] <<
' ';
175 std::cout << std::endl;
179 template <
typename T>
180 inline constexpr void _from(
T v) {
185#elif defined(__GNUC__)
188 for (; bytes_used < bytes_needed<N>(); bytes_used++) {
189 storage[bytes_used] = v & 0x7f;
191 if ((v == -1 && (storage[bytes_used] & 0x40)) || (v == 0 && !(storage[bytes_used] & 0x40)))
193 storage[bytes_used] |= 0x80;
198 template <
typename T>
199 inline constexpr T _to() {
200 typename std::make_unsigned<T>::type
ret = 0;
204#elif defined(__GNUC__)
207 for (
int i=bytes_used-1; i >= 0; i--) {
209 ret |= storage[i] & 0x7f;
212 size_t shift = ((bytes_used) * 7);
213 if (storage[bytes_used-1] & 0x40)
214 ret |= (-1ull) << shift;
219 std::array<uint8_t, bytes_needed<N>()> storage;
constexpr varint(guarded_ptr< uint8_t > &code)
constexpr void from(int8_t v)
constexpr void from(int64_t v)
constexpr varint(int64_t v)
constexpr varint(int8_t v)
constexpr void from(int32_t v)
constexpr varint(int32_t v)
constexpr void from(guarded_ptr< uint8_t > &code)
constexpr varuint(bool v)
constexpr void from(bool v)
constexpr void from(uint32_t v)
constexpr varuint(uint32_t v)
constexpr varuint(guarded_ptr< uint8_t > &code)
constexpr varuint(uint8_t v)
constexpr void from(guarded_ptr< uint8_t > &code)
constexpr void from(uint8_t v)
size_t constexpr bytes_needed()
#define T(meth, val, expected)
#define SYS_VM_ASSERT(expr, exc_type, msg)