From 1afc566df942e82f70d2e82e33c0e39539714ad5 Mon Sep 17 00:00:00 2001 From: ludamad Date: Wed, 13 Sep 2023 09:46:03 -0400 Subject: [PATCH] fix: msgpack stack blowups on schema gen (#2259) --- .../serialize/msgpack_impl/check_memory_span.hpp | 9 +++++---- .../serialize/msgpack_impl/schema_impl.hpp | 11 ++++++++--- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/circuits/cpp/barretenberg/cpp/src/barretenberg/serialize/msgpack_impl/check_memory_span.hpp b/circuits/cpp/barretenberg/cpp/src/barretenberg/serialize/msgpack_impl/check_memory_span.hpp index a9d7abe01ed..deac75683b3 100644 --- a/circuits/cpp/barretenberg/cpp/src/barretenberg/serialize/msgpack_impl/check_memory_span.hpp +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/serialize/msgpack_impl/check_memory_span.hpp @@ -59,18 +59,19 @@ template std::string check_memory_span(T* obj, Ar return {}; } -template std::string check_msgpack_method(T& object) +template std::string check_msgpack_method(const T& object) { std::string result; auto checker = [&](auto&... values) { result = check_memory_span(&object, &values...); }; - object.msgpack([&](auto&... keys_and_values) { std::apply(checker, drop_keys(std::tie(keys_and_values...))); }); + const_cast(object).msgpack( // NOLINT + [&](auto&... keys_and_values) { std::apply(checker, drop_keys(std::tie(keys_and_values...))); }); return result; } -void check_msgpack_usage(auto object) +void check_msgpack_usage(const auto& object) { std::string result = check_msgpack_method(object); if (!result.empty()) { throw_or_abort(result); } } -} // namespace msgpack \ No newline at end of file +} // namespace msgpack diff --git a/circuits/cpp/barretenberg/cpp/src/barretenberg/serialize/msgpack_impl/schema_impl.hpp b/circuits/cpp/barretenberg/cpp/src/barretenberg/serialize/msgpack_impl/schema_impl.hpp index a17041517c0..758db242bcd 100644 --- a/circuits/cpp/barretenberg/cpp/src/barretenberg/serialize/msgpack_impl/schema_impl.hpp +++ b/circuits/cpp/barretenberg/cpp/src/barretenberg/serialize/msgpack_impl/schema_impl.hpp @@ -66,7 +66,7 @@ struct MsgpackSchemaPacker : msgpack::packer { // Note: if this fails to compile, check first in list of template Arg's // it may need a msgpack_schema_pack specialization (particularly if it doesn't define MSGPACK_FIELDS). - (_msgpack_schema_pack(*this, Args{}), ...); /* pack schemas of all template Args */ + (_msgpack_schema_pack(*this, *std::make_unique()), ...); /* pack schemas of all template Args */ } /** * @brief Encode a type that defines msgpack based on its key value pairs. @@ -108,7 +108,10 @@ concept SchemaPackable = requires(T value, MsgpackSchemaPacker packer) { msgpack // Helper for packing (key, value, key, value, ...) arguments template -inline void _schema_pack_map_content(MsgpackSchemaPacker& packer, std::string key, Value value, Rest... rest) +inline void _schema_pack_map_content(MsgpackSchemaPacker& packer, + std::string key, + const Value& value, + const Rest&... rest) { static_assert( msgpack_concepts::SchemaPackable, @@ -200,7 +203,9 @@ inline void msgpack_schema_pack(MsgpackSchemaPacker& packer, std::array co packer.pack("array"); // That has a size 2 tuple as its 2nd arg packer.pack_array(2); /* param list format for consistency*/ - _msgpack_schema_pack(packer, T{}); + // To avoid WASM problems with large stack objects, we use a heap allocation. + // Small note: This works because make_unique goes of scope only when the whole line is done. + _msgpack_schema_pack(packer, *std::make_unique()); packer.pack(N); }