Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
msgpack_impl.hpp
Go to the documentation of this file.
1#pragma once
2// Meant to be the main header included by *.cpp files* that use msgpack.
3// Note: heavy header due to serialization logic, don't include if msgpack.hpp will do
4// CBinding helpers that take a function or a lambda and
5// - bind the input as a coded msgpack array of all the arguments (using template metamagic)
6// - bind the return value to an out buffer, where the caller must free the memory
7
8#include <cstring>
9#include <type_traits>
10
20
29 uint8_t* scratch_buf = nullptr,
30 size_t scratch_size = 0)
31{
32 // Create a buffer to store the encoded data
33 msgpack::sbuffer buffer;
34 msgpack::pack(buffer, obj);
35
36 // If scratch buffer provided and result fits, use it
37 if (scratch_buf != nullptr && buffer.size() <= scratch_size) {
38 memcpy(scratch_buf, buffer.data(), buffer.size());
39 return { scratch_buf, buffer.size() };
40 }
41
42 // Otherwise allocate new buffer
43 uint8_t* output = static_cast<uint8_t*>(aligned_alloc(64, buffer.size()));
44 memcpy(output, buffer.data(), buffer.size());
45 return { output, buffer.size() };
46}
47
48// This function is intended to bind a function to a MessagePack-formatted input data,
49// perform the function with the unpacked data, then pack the result back into MessagePack format.
50// Note: output_out and output_len_out are IN-OUT parameters:
51// IN: Caller provides scratch buffer pointer and size
52// OUT: Returns actual result buffer (may be scratch or newly allocated) and size
53inline void msgpack_cbind_impl(const auto& func, // The function to be applied
54 const uint8_t* input_in, // The input data in MessagePack format
55 size_t input_len_in, // The length of the input data
56 uint8_t** output_out, // IN-OUT: scratch buffer ptr / result buffer ptr
57 size_t* output_len_out) // IN-OUT: scratch buffer size / result size
58{
59 using FuncTraits = decltype(get_func_traits<decltype(func)>());
60 // Args: the parameter types of the function as a tuple.
61 typename FuncTraits::Args params;
62
63 // Unpack the input data into the parameter tuple.
64 msgpack::unpack(reinterpret_cast<const char*>(input_in), input_len_in).get().convert(params);
65
66 // Read IN values: caller-provided scratch buffer
67 uint8_t* scratch_buf = *output_out;
68 size_t scratch_size = *output_len_out;
69
70 // Apply the function to the parameters, then encode the result into a MessagePack buffer.
71 // Try to use scratch buffer; allocate if result doesn't fit.
72 auto [output, output_len] = msgpack_encode_buffer(FuncTraits::apply(func, params), scratch_buf, scratch_size);
73
74 // Write OUT values: actual result buffer and size
75 // If result fit in scratch, output == scratch_buf (pointer unchanged)
76 // If result didn't fit, output is newly allocated buffer (pointer changed)
77 *output_out = output;
78 *output_len_out = output_len;
79}
80
81// returns a C-style string json of the schema
82inline void msgpack_cbind_schema_impl(auto func, uint8_t** output_out, size_t* output_len_out)
83{
84 (void)func; // unused except for type
85 // Object representation of the cbind
86 auto cbind_obj = get_func_traits<decltype(func)>();
87 std::string schema = msgpack_schema_to_string(cbind_obj);
88 *output_out = static_cast<uint8_t*>(aligned_alloc(64, schema.size() + 1));
89 memcpy(*output_out, schema.c_str(), schema.size() + 1);
90 *output_len_out = schema.size();
91}
92
93// The CBIND_NOSCHEMA macro generates a function named 'cname' that decodes the input arguments from msgpack format,
94// calls the target function, and then encodes the return value back into msgpack format. It should be used over CBIND
95// in cases where we do not want schema generation, such as meta-functions that themselves give information to control
96// how the schema is interpreted.
97#define CBIND_NOSCHEMA(cname, func) \
98 WASM_EXPORT void cname(const uint8_t* input_in, size_t input_len_in, uint8_t** output_out, size_t* output_len_out) \
99 { \
100 msgpack_cbind_impl(func, input_in, input_len_in, output_out, output_len_out); \
101 }
102
103// The CBIND macro is a convenient utility that abstracts away several steps in binding C functions with msgpack
104// serialization. It creates two separate functions:
105// 1. cname function: This decodes the input arguments from msgpack format, calls the target function,
106// and then encodes the return value back into msgpack format.
107// 2. cname##__schema function: This creates a JSON schema of the function's input arguments and return type.
108#define CBIND(cname, func) \
109 CBIND_NOSCHEMA(cname, func) \
110 WASM_EXPORT void cname##__schema(uint8_t** output_out, size_t* output_len_out) \
111 { \
112 msgpack_cbind_schema_impl(func, output_out, output_len_out); \
113 }
uint8_t buffer[RANDOM_BUFFER_SIZE]
Definition engine.cpp:34
void msgpack_cbind_impl(const auto &func, const uint8_t *input_in, size_t input_len_in, uint8_t **output_out, size_t *output_len_out)
void msgpack_cbind_schema_impl(auto func, uint8_t **output_out, size_t *output_len_out)
std::pair< uint8_t *, size_t > msgpack_encode_buffer(auto &&obj, uint8_t *scratch_buf=nullptr, size_t scratch_size=0)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
std::string msgpack_schema_to_string(const auto &obj)
Print's an object's derived msgpack schema as a string.