3#include <barretenberg/serialize/msgpack_impl/msgpack_impl.hpp>
5#include "barretenberg/common/throw_or_abort.hpp"
6#include "schema_name.hpp"
14template <
typename T> uintptr_t __aligned_for(uintptr_t ptr)
17 return ptr + (
alignof(T) - (ptr %
alignof(T))) %
alignof(T);
19template <
typename T,
typename... Args> std::string check_memory_span(T* obj, Args*... args)
24 std::vector<std::pair<uintptr_t, size_t>> pointers{ { (uintptr_t)(args),
sizeof(Args) }... };
26 std::sort(pointers.begin(), pointers.end(), [](
const auto& a,
const auto& b) { return a.first < b.first; });
28 for (
size_t i = 1; i < pointers.size(); ++i) {
30 auto last_end = pointers[i - 1].first + pointers[i - 1].second;
31 if (last_end > pointers[i].first) {
32 return "Overlap in " + msgpack_schema_name(*obj) +
" MSGPACK_FIELDS() params detected!";
36 if (__aligned_for<T>(last_end) < pointers[i].first) {
37 return "Gap in " + msgpack_schema_name(*obj) +
" MSGPACK_FIELDS() params detected before member #" +
38 std::to_string(i) +
" !";
43 uintptr_t t_start =
reinterpret_cast<uintptr_t
>(obj);
44 uintptr_t t_end = t_start +
sizeof(T);
45 if (pointers.front().first < t_start || pointers.back().first + pointers.back().second > t_end) {
46 return "Some " + msgpack_schema_name(*obj) +
" MSGPACK_FIELDS() params don't exist in object!";
50 size_t start = (size_t)obj;
51 size_t end = (size_t)obj;
52 for (
auto [ptr, size] : pointers) {
53 end = std::max(end, ptr + size);
55 size_t total_size = end - start;
56 if (__aligned_for<T>(total_size) <
sizeof(T)) {
57 return "Incomplete " + msgpack_schema_name(*obj) +
" MSGPACK_FIELDS() params! Not all of object specified.";
62template <msgpack_concepts::HasMsgPack T> std::string check_msgpack_method(
const T&
object)
65 auto checker = [&](
auto&... values) { result = check_memory_span(&
object, &values...); };
66 const_cast<T&
>(object).msgpack(
67 [&](
auto&... keys_and_values) { std::apply(checker, drop_keys(std::tie(keys_and_values...))); });
70void check_msgpack_usage(
const auto&
object)
72 std::string result = check_msgpack_method(
object);
73 if (!result.empty()) {
74 throw_or_abort(result);