Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

flatbuf #403

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:
build-cpp:
name: Build C++
runs-on: ubuntu-latest
container: ghcr.io/eoscommunity/eden-builder:sub-chain
container: ghcr.io/eoscommunity/eden-builder:flatbuf

steps:
- name: ✅ Checkout code
Expand Down
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,15 @@ sudo apt-get install -yq \
build-essential \
cmake \
git \
libboost-all-dev \
libcurl4-openssl-dev \
libgbm-dev \
libgmp-dev \
libnss3-dev \
libssl-dev \
libusb-1.0-0-dev \
libz-dev \
pkg-config \
python \
wget

export WASI_SDK_PREFIX=~/work/wasi-sdk-12.0
Expand All @@ -60,4 +61,12 @@ tar xf wasi-sdk-12.0-linux.tar.gz
wget https://nodejs.org/dist/v14.16.0/node-v14.16.0-linux-x64.tar.xz
tar xf node-v14.16.0-linux-x64.tar.xz
npm i -g yarn

# Install boost 1.75 or later. e.g. this installs it in /usr/local:
curl -LO https://github.com/eoscommunity/Eden/releases/download/deps/boost_1_75_0.tar.bz2
tar xf boost_1_75_0.tar.bz2
cd boost_1_75_0
./bootstrap.sh
./b2
sudo ./b2 --without-python install
```
12 changes: 11 additions & 1 deletion docker/eden-builder.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ RUN export DEBIAN_FRONTEND=noninteractive \
cmake \
curl \
git \
libboost-all-dev \
libcurl4-openssl-dev \
libgmp-dev \
libssl-dev \
libusb-1.0-0-dev \
libz-dev \
libzstd-dev \
pkg-config \
python \
&& apt-get clean -yq \
&& rm -rf /var/lib/apt/lists/*

Expand All @@ -37,5 +38,14 @@ RUN cd /opt \
&& export PATH="/opt/node-v14.16.0-linux-x64/bin:$PATH" \
&& npm i -g yarn

RUN cd /root \
&& curl -LO https://github.com/eoscommunity/Eden/releases/download/deps/boost_1_75_0.tar.bz2 \
&& tar xf boost_1_75_0.tar.bz2 \
&& cd boost_1_75_0 \
&& ./bootstrap.sh \
&& ./b2 --without-python install \
&& cd /root \
&& rm -rf boost_*

ENV WASI_SDK_PREFIX=/opt/wasi-sdk-12.0
ENV PATH=/opt/node-v14.16.0-linux-x64/bin:$PATH
113 changes: 113 additions & 0 deletions libraries/abieos/include/eosio/member_proxy.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#pragma once

namespace eosio
{
// Note: This (and flatbuf) rely on implicitly creating objects. This feature was added to C++17
// and C++20 via a DR resolution (P0593R6). However, P0593R6 doesn't circumvent
// strict-aliasing requirements. The proxy objects overlay (alias) with the actual data.
// e.g. an object_proxy followed by 3 member_proxy's may occupy the same space as a
// uint32_t. We're assuming that since the proxies have no non-static data members, calling
// their member functions won't cause issues. We could move the member functions outside of
// the proxies, but that will probably create an inconvenient API.

/**
* member_proxy is a member of a type (eosio_proxy) created by a macro. I is the member number in
* the containing type. The containing type's first member is an ObjectProxy. proxyptr() does the
* pointer math necessary to find the ObjectProxy.
*
* Alternatively the macro code would have to initialize every member_proxy with this, which
* would bloat the size of the eosio_proxy object.
*
* flat_view<T> => eosio_proxy<T, ObjectProxy>
*
* struct eosio_proxy<T, ObjectProxy> {
* ObjectProxy object_proxy;
* member_proxy<0, ptr, ObjectProxy> member_zero
* member_proxy<1, ptr, ObjectProxy> member_one
* member_proxy<2, ptr, ObjectProxy> member_two
* }
*
* Let char* buf = point to a flat buffer;
* reinterpret buf as eosio_proxy<T, ObjectProxy>, this makes the address of object_proxy
* equal to the address of eosio_proxy because it is the first element.
*
* because member_proxy has no values it takes 1 byte in member_proxy and the value of that byte
* is never read by member_proxy... member_proxy always gets the address of object_proxy and
* then does offset math.
*/
template <uint32_t I, auto mptr, typename ObjectProxy>
struct member_proxy
{
constexpr auto proxyptr() const
{
return (reinterpret_cast<const ObjectProxy*>(reinterpret_cast<const char*>(this) -
sizeof(*this) * I - sizeof(ObjectProxy)));
}
constexpr auto proxyptr()
{
return (reinterpret_cast<ObjectProxy*>(reinterpret_cast<char*>(this) - sizeof(*this) * I -
sizeof(ObjectProxy)));
}
constexpr const auto& get() const { return *(proxyptr()->template get<I, mptr>()); }
constexpr auto& get() { return *(proxyptr()->template get<I, mptr>()); }

template <typename... Ts>
constexpr auto operator()(Ts&&... args)
{
return proxyptr()->template call<I, mptr>(std::forward<Ts>(args)...);
}
template <typename... Ts>
constexpr auto operator()(Ts&&... args) const
{
return proxyptr()->template call<I, mptr>(std::forward<Ts>(args)...);
}

constexpr auto operator->() { return (proxyptr()->template get<I, mptr>()); }
constexpr const auto operator->() const { return (proxyptr()->template get<I, mptr>()); }

constexpr auto& operator*() { return get(); }
constexpr const auto& operator*() const { return get(); }

template <typename T>
constexpr auto& operator[](T&& k)
{
return get()[std::forward<T>(k)];
}

template <typename T>
constexpr const auto& operator[](T&& k) const
{
return get()[std::forward<T>(k)];
}

template <typename S>
friend S& operator<<(S& stream, const member_proxy& member)
{
return stream << member.get();
}

template <typename R>
auto operator=(R&& r)
{
get() = std::forward<R>(r);
return *this;
}

// template <typename R>
// operator R() const
// {
// return get();
// }

/*
operator decltype( ((ObjectProxy*)nullptr)->template get<I,mptr>())()
{ return get(); }
operator decltype( ((const ObjectProxy*)nullptr)->template get<I,mptr>()) ()const
{ return get(); }
*/
};

// TODO
template <uint32_t I, typename T, typename Base, typename ObjectProxy>
struct base_proxy;
} // namespace eosio
73 changes: 54 additions & 19 deletions libraries/abieos/include/eosio/reflection2.hpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
#include <eosio/member_proxy.hpp>
#include <eosio/reflection.hpp>

#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/control/iif.hpp>
#include <boost/preprocessor/facilities/check_empty.hpp>
#include <boost/preprocessor/logical/bitand.hpp>
#include <boost/preprocessor/logical/compl.hpp>
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/seq/for_each_i.hpp>
#include <boost/preprocessor/stringize.hpp>
#include <boost/preprocessor/tuple/push_front.hpp>
#include <boost/preprocessor/variadic/to_seq.hpp>
Expand All @@ -17,36 +18,58 @@

#define EOSIO_REFLECT2_FIRST(a, ...) a
#define EOSIO_REFLECT2_APPLY_FIRST(a) EOSIO_REFLECT2_FIRST(a)
#define EOSIO_REFLECT2_SKIP_SECOND(a, b, ...) (a, __VA_ARGS__)
#define EOSIO_REFLECT2_FLATTEN(...) (__VA_ARGS__)

#define EOSIO_REFLECT2_KNOWN_ITEM(STRUCT, item) \
EOSIO_REFLECT2_FIRST EOSIO_REFLECT2_APPLY_FIRST(BOOST_PP_CAT(EOSIO_REFLECT2_MATCH_ITEM, item)) \
EOSIO_REFLECT2_SKIP_SECOND BOOST_PP_TUPLE_PUSH_FRONT( \
EOSIO_REFLECT2_APPLY_FIRST(BOOST_PP_CAT(EOSIO_REFLECT2_MATCH_ITEM, item)), STRUCT)
#define EOSIO_REFLECT2_MATCH_ITEM(r, STRUCT, item) \
BOOST_PP_IIF(BOOST_PP_CHECK_EMPTY(item), , \
BOOST_PP_IIF(EOSIO_REFLECT2_MATCH(EOSIO_REFLECT2_MATCH_ITEM, item), \
EOSIO_REFLECT2_KNOWN_ITEM, EOSIO_REFLECT2_MEMBER)(STRUCT, item))
#define EOSIO_REFLECT2_MATCH_ITEM_IMPL(r, STRUCT, i, item, MATCHED_ITEM, UNMATCHED_ITEM) \
BOOST_PP_IIF(BOOST_PP_CHECK_EMPTY(item), , \
BOOST_PP_IIF(EOSIO_REFLECT2_MATCH(EOSIO_REFLECT2_MATCH_ITEM, item), MATCHED_ITEM, \
UNMATCHED_ITEM)(STRUCT, i, item))

#define EOSIO_REFLECT2_MEMBER(STRUCT, member) \
#define EOSIO_REFLECT2_MATCHED_ITEM(STRUCT, i, item) \
BOOST_PP_CAT(EOSIO_REFLECT2_, \
EOSIO_REFLECT2_APPLY_FIRST(BOOST_PP_CAT(EOSIO_REFLECT2_MATCH_ITEM, item))) \
EOSIO_REFLECT2_FLATTEN(i, STRUCT, BOOST_PP_CAT(EOSIO_REFLECT2_ARGS, item))
#define EOSIO_REFLECT2_UNMATCHED_ITEM(STRUCT, i, member) \
f(#member, [](auto p) -> decltype(&std::decay_t<decltype(*p)>::member) { \
return &std::decay_t<decltype(*p)>::member; \
});
#define EOSIO_REFLECT2_MATCH_ITEM(r, STRUCT, i, item) \
EOSIO_REFLECT2_MATCH_ITEM_IMPL(r, STRUCT, i, item, EOSIO_REFLECT2_MATCHED_ITEM, \
EOSIO_REFLECT2_UNMATCHED_ITEM)

#define EOSIO_REFLECT2_MATCH_ITEMbase(...) (EOSIO_REFLECT2_base, __VA_ARGS__), 1
#define EOSIO_REFLECT2_base(STRUCT, base) \
#define EOSIO_REFLECT2_MATCHED_PROXY(STRUCT, i, item) \
BOOST_PP_CAT(EOSIO_REFLECT2_PROXY_, \
EOSIO_REFLECT2_APPLY_FIRST(BOOST_PP_CAT(EOSIO_REFLECT2_MATCH_ITEM, item))) \
EOSIO_REFLECT2_FLATTEN(i, STRUCT, BOOST_PP_CAT(EOSIO_REFLECT2_ARGS, item))
#define EOSIO_REFLECT2_PROXY(STRUCT, i, member) \
std::remove_reference_t<decltype( \
std::declval<eosio::member_proxy<i, &STRUCT::member, ObjectProxy>>())> \
member;
#define EOSIO_REFLECT2_MATCH_PROXY(r, STRUCT, i, item) \
EOSIO_REFLECT2_MATCH_ITEM_IMPL(r, STRUCT, i, item, EOSIO_REFLECT2_MATCHED_PROXY, \
EOSIO_REFLECT2_PROXY)

#define EOSIO_REFLECT2_MATCH_ITEMbase(...) base, 1
#define EOSIO_REFLECT2_ARGSbase(...) __VA_ARGS__
#define EOSIO_REFLECT2_base(i, STRUCT, base) \
static_assert(std::is_base_of_v<base, STRUCT>, \
BOOST_PP_STRINGIZE(base) " is not a base class of " BOOST_PP_STRINGIZE(STRUCT)); \
eosio_for_each_field((base*)nullptr, f);
#define EOSIO_REFLECT2_PROXY_base(i, STRUCT, BASE) \
std::remove_reference_t<decltype( \
std::declval<eosio::base_proxy<i, STRUCT, BASE, ObjectProxy>>())> \
base;

#define EOSIO_REFLECT2_MATCH_ITEMmethod(...) (EOSIO_REFLECT2_method, __VA_ARGS__), 1
#define EOSIO_REFLECT2_method(STRUCT, member, ...) \
#define EOSIO_REFLECT2_MATCH_ITEMmethod(...) method, 1
#define EOSIO_REFLECT2_ARGSmethod(...) __VA_ARGS__
#define EOSIO_REFLECT2_method(i, STRUCT, member, ...) \
f( \
BOOST_PP_STRINGIZE(member), \
[](auto p) -> decltype(&std::decay_t<decltype(*p)>::member) { \
return &std::decay_t<decltype(*p)>::member; \
}, \
__VA_ARGS__);
#define EOSIO_REFLECT2_PROXY_method(i, STRUCT, member, ...) EOSIO_REFLECT2_PROXY(STRUCT, i, member)

/**
* EOSIO_REFLECT2(<struct>, <member or base spec>...)
Expand All @@ -60,9 +83,21 @@
template <typename F> \
constexpr void eosio_for_each_field(STRUCT*, F f) \
{ \
BOOST_PP_SEQ_FOR_EACH(EOSIO_REFLECT2_MATCH_ITEM, STRUCT, \
BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) \
}
BOOST_PP_SEQ_FOR_EACH_I(EOSIO_REFLECT2_MATCH_ITEM, STRUCT, \
BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) \
} \
template <typename T, typename ObjectProxy> \
struct eosio_proxy; \
template <typename ObjectProxy> \
struct eosio_proxy<STRUCT, ObjectProxy> \
{ \
ObjectProxy object_proxy; \
BOOST_PP_SEQ_FOR_EACH_I(EOSIO_REFLECT2_MATCH_PROXY, \
STRUCT, \
BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) \
}; \
template <typename ObjectProxy> \
eosio_proxy<STRUCT, ObjectProxy> eosio_get_proxy_type(const STRUCT*, const ObjectProxy*);

#define EOSIO_REFLECT2_FOR_EACH_FIELD(STRUCT, ...) \
BOOST_PP_SEQ_FOR_EACH(EOSIO_REFLECT2_MATCH_ITEM, STRUCT, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))
BOOST_PP_SEQ_FOR_EACH_I(EOSIO_REFLECT2_MATCH_ITEM, STRUCT, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))
8 changes: 8 additions & 0 deletions libraries/abieos/include/eosio/stream.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,12 @@ namespace eosio
{
write(&v, sizeof(v));
}

void skip(size_t size)
{
check(size <= size_t(end - pos), convert_stream_error(stream_error::overrun));
pos += size;
}
};

struct size_stream
Expand All @@ -157,6 +163,8 @@ namespace eosio
{
size += sizeof(v);
}

void skip(size_t sz) { size += sz; }
};

template <typename S>
Expand Down
22 changes: 22 additions & 0 deletions libraries/abieos/include/eosio/types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,17 @@ namespace eosio
template <typename T>
using tuple_from_type_list = decltype(tuple_from_type_list_impl(std::declval<T>()));

template <typename T>
struct member_object;

template <typename T, typename M>
struct member_object<M(T::*)>
{
using type = M(T::*);
using class_type = T;
using member_type = M;
};

template <typename T>
struct member_fn;

Expand Down Expand Up @@ -139,6 +150,17 @@ namespace eosio
using value_type = T;
};

template <typename T>
struct is_std_vector : std::false_type
{
};

template <typename T>
struct is_std_vector<std::vector<T>> : std::true_type
{
using value_type = T;
};

template <typename T>
struct is_binary_extension : std::false_type
{
Expand Down
3 changes: 3 additions & 0 deletions libraries/clchain/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
enable_testing()
find_package(OpenSSL REQUIRED Crypto)

function(add suffix)
Expand All @@ -24,3 +25,5 @@ add("")
if(DEFINED IS_WASM)
add("-debug")
endif()

add_subdirectory(tests)
Loading