Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
wasm_stack.hpp
Go to the documentation of this file.
1#pragma once
2
3/*
4 * definitions from https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md
5 */
6
7#include <sysio/vm/allocator.hpp>
8#include <sysio/vm/constants.hpp>
9#include <sysio/vm/exceptions.hpp>
10#include <sysio/vm/stack_elem.hpp>
11#include <sysio/vm/types.hpp>
12#include <sysio/vm/vector.hpp>
13
14namespace sysio { namespace vm {
15 using std::nullptr_t;
16
17 template <typename ElemT, size_t ElemSz, typename Allocator = nullptr_t >
18 class stack {
19 public:
20 template <typename Alloc=Allocator, typename = std::enable_if_t<std::is_same_v<Alloc, std::nullptr_t>, int>>
22 : _store(ElemSz) {}
23
24 template <typename Alloc=Allocator, typename = std::enable_if_t<!std::is_same_v<Alloc, nullptr_t>, int>>
25 stack(Alloc&& alloc)
26 : _store(alloc, ElemSz) {}
27
28 template <typename Alloc=Allocator, typename = std::enable_if_t<!std::is_same_v<Alloc, nullptr_t>, int>>
29 stack(uint32_t n, Alloc&& alloc)
30 : _store(alloc, n) {}
31
32 void push(ElemT&& e) {
33 if constexpr (std::is_same_v<Allocator, nullptr_t>) {
34 if (_index >= _store.size())
35 _store.resize(_store.size()*2);
36 }
37 _store[_index++] = std::forward<ElemT>(e);
38 }
39
40 ElemT pop() { return _store[--_index]; }
41
42 ElemT& get(uint32_t index) const {
43 SYS_VM_ASSERT(index <= _index, wasm_interpreter_exception, "invalid stack index");
44 return (ElemT&)_store[index];
45 }
46 void set(uint32_t index, const ElemT& el) {
47 SYS_VM_ASSERT(index <= _index, wasm_interpreter_exception, "invalid stack index");
48 _store[index] = el;
49 }
50 void eat(uint32_t index) { _index = index; }
51 // compact the last element to the element pointed to by index
52 void compact(uint32_t index) {
53 _store[index] = _store[_index-1];
54 _index = index+1;
55 }
56 size_t current_index() const { return _index; }
57 ElemT& peek() { return _store[_index - 1]; }
58 const ElemT& peek() const { return _store[_index - 1]; }
59 ElemT& peek(size_t i) { return _store[_index - 1 - i]; }
60 ElemT& get_back(size_t i) { return _store[_index - 1 - i]; }
61 const ElemT& get_back(size_t i)const { return _store[_index - 1 - i]; }
62 void trim(size_t amt) { _index -= amt; }
63 size_t size() const { return _index; }
64 size_t capacity() const { return _store.size(); }
65
66 private:
67 using base_data_store_t = std::conditional_t<std::is_same_v<Allocator, std::nullptr_t>, unmanaged_vector<ElemT>, managed_vector<ElemT, Allocator>>;
68
69 base_data_store_t _store;
70 size_t _index = 0;
71 };
72
75
76}} // namespace sysio::vm
void set(uint32_t index, const ElemT &el)
ElemT & get_back(size_t i)
const ElemT & peek() const
const ElemT & get_back(size_t i) const
ElemT & get(uint32_t index) const
void compact(uint32_t index)
size_t capacity() const
void eat(uint32_t index)
size_t current_index() const
stack(uint32_t n, Alloc &&alloc)
stack(Alloc &&alloc)
void push(ElemT &&e)
ElemT & peek(size_t i)
size_t size() const
void trim(size_t amt)
std::vector< T > unmanaged_vector
Definition vector.hpp:108
unsigned int uint32_t
Definition stdint.h:126
#define SYS_VM_ASSERT(expr, exc_type, msg)
Definition exceptions.hpp:8