[libc-commits] [libc] [llvm] [libc] Add RPC helpers for dispatching functions to the host (PR #179085)
Shilei Tian via libc-commits
libc-commits at lists.llvm.org
Tue Feb 10 10:57:06 PST 2026
================
@@ -0,0 +1,268 @@
+//===-- Helper functions for client / server dispatch -----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "rpc.h"
+#include "rpc_util.h"
+
+namespace rpc {
+namespace {
+
+// Forward declarations needed for the server, we assume these are present.
+extern "C" void *malloc(uint64_t);
+extern "C" void free(const void *);
+
+// Traits to convert between a tuple and binary representation of an argument
+// list.
+template <typename... Ts> struct tuple_bytes {
+ static constexpr uint64_t SIZE = rpc::max(1ul, (0 + ... + sizeof(Ts)));
+ using array_type = rpc::array<uint8_t, SIZE>;
+
+ template <uint64_t... Is>
+ RPC_ATTRS static constexpr array_type pack_impl(rpc::tuple<Ts...> t,
+ rpc::index_sequence<Is...>) {
+ array_type out{};
+ uint8_t *p = out.data();
+ ((rpc::rpc_memcpy(p, &rpc::get<Is>(t), sizeof(Ts)), p += sizeof(Ts)), ...);
+ return out;
+ }
+
+ RPC_ATTRS static constexpr array_type pack(rpc::tuple<Ts...> t) {
+ return pack_impl(t, rpc::index_sequence_for<Ts...>{});
+ }
+
+ template <uint64_t... Is>
+ RPC_ATTRS static constexpr rpc::tuple<Ts...>
+ unpack_impl(const uint8_t *data, rpc::index_sequence<Is...>) {
+ rpc::tuple<Ts...> t{};
+ const uint8_t *p = data;
+ ((rpc::rpc_memcpy(&rpc::get<Is>(t), p, sizeof(Ts)), p += sizeof(Ts)), ...);
+ return t;
+ }
+
+ RPC_ATTRS static constexpr rpc::tuple<Ts...> unpack(const array_type &a) {
+ return unpack_impl(a.data(), rpc::index_sequence_for<Ts...>{});
+ }
+};
+template <typename... Ts>
+struct tuple_bytes<rpc::tuple<Ts...>> : tuple_bytes<Ts...> {};
+
+template <typename> struct function_traits;
+template <typename R, typename... Args> struct function_traits<R (*)(Args...)> {
+ using return_type = R;
+ using arg_types = rpc::tuple<Args...>;
+ static constexpr uint64_t ARITY = sizeof...(Args);
+};
+
+// Client-side dispatch of pointer values. We copy the memory associated with
+// the pointer to the server and recieve back a server-side pointer to replace
+// the client-side pointer in the argument list.
+template <uint64_t Idx, typename Tuple>
+RPC_ATTRS constexpr void prepare_arg(rpc::Client::Port &port, Tuple &t) {
+ using ArgTy = rpc::tuple_element_t<Idx, Tuple>;
+ if constexpr (rpc::is_pointer_v<ArgTy> &&
+ !rpc::is_void_v<rpc::remove_pointer_t<ArgTy>>) {
+ // We assume all constant character arrays are C-strings.
+ uint64_t size{};
+ if constexpr (rpc::is_same_v<ArgTy, const char *>)
+ size = rpc::string_length(rpc::get<Idx>(t));
----------------
shiltian wrote:
Using `string_length` has a drawback that it would return wrong results if there is any 0 in the memory buffer. How do you plan to tackle that?
https://github.com/llvm/llvm-project/pull/179085
More information about the libc-commits
mailing list