From c68b6cbe3cd3e3424f6cf561731414fe6c62e4fd Mon Sep 17 00:00:00 2001 From: Diego Nehab <1635557+diegonehab@users.noreply.github.com> Date: Mon, 16 Dec 2024 15:39:59 +0000 Subject: [PATCH] refactor: split cm_new and cm_clone_empty --- src/clua-cartesi.cpp | 4 ++-- src/clua-i-virtual-machine.cpp | 7 +++---- src/machine-c-api.cpp | 32 ++++++++++++++++++++++---------- src/machine-c-api.h | 21 +++++++++++++++------ 4 files changed, 42 insertions(+), 22 deletions(-) diff --git a/src/clua-cartesi.cpp b/src/clua-cartesi.cpp index cb6d2ed6..beccff0f 100644 --- a/src/clua-cartesi.cpp +++ b/src/clua-cartesi.cpp @@ -136,7 +136,7 @@ static int cartesi_mod_fromjson(lua_State *L) try { static int cartesi_mod_new(lua_State *L) try { auto &m = clua_push_to(L, clua_managed_cm_ptr(nullptr)); - if (cm_new(nullptr, &m.get()) != 0) { + if (cm_new(&m.get()) != 0) { return luaL_error(L, "%s", cm_get_last_error_message()); } return 1; @@ -181,7 +181,7 @@ CM_API int luaopen_cartesi(lua_State *L) { lua_pushvalue(L, -2); // cluactx cartesi cluactx luaL_setfuncs(L, cartesi_mod.data(), 1); // cluactx cartesi auto &m = clua_push_to(L, clua_managed_cm_ptr(nullptr), -2); // cluactx cartesi machine - if (cm_new(nullptr, &m.get()) != 0) { + if (cm_new(&m.get()) != 0) { return luaL_error(L, "%s", cm_get_last_error_message()); } lua_setfield(L, -2, "machine"); // cluactx cartesi diff --git a/src/clua-i-virtual-machine.cpp b/src/clua-i-virtual-machine.cpp index d74ac363..d74849e5 100644 --- a/src/clua-i-virtual-machine.cpp +++ b/src/clua-i-virtual-machine.cpp @@ -1166,11 +1166,10 @@ static int machine_meta_call(lua_State *L) { lua_settop(L, 3); auto &m = clua_check>(L, 1); // source machine // We could be creating a local machine or a remote machine. - // The type is decided by source machine, which will be a cm_machine created with - // either cm_new(nullptr, ...) or with cm_jsonrpc_connect_server/spawn_server/fork_server - // When we call cm_new(m.get(), ...), it creates a new empty object from the same underlying type as m.get(). + // When we call cm_clone_empty(m.get(), ...), it creates a new empty object from the same underlying type as + // m.get(). auto &new_m = clua_push_to(L, clua_managed_cm_ptr(nullptr)); - if (cm_new(m.get(), &new_m.get()) != 0) { + if (cm_clone_empty(m.get(), &new_m.get()) != 0) { return luaL_error(L, "%s", cm_get_last_error_message()); } const char *runtime_config = !lua_isnil(L, 3) ? clua_check_json_string(L, 3) : nullptr; diff --git a/src/machine-c-api.cpp b/src/machine-c-api.cpp index b0bc7e3e..22f51426 100644 --- a/src/machine-c-api.cpp +++ b/src/machine-c-api.cpp @@ -141,6 +141,11 @@ static const cartesi::i_virtual_machine *convert_from_c(const cm_machine *m) { return reinterpret_cast(m); } +static cm_machine *convert_to_c(cartesi::i_virtual_machine *cpp_m) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + return reinterpret_cast(cpp_m); +} + cartesi::machine_merkle_tree::hash_type convert_from_c(const cm_hash *c_hash) { if (c_hash == nullptr) { throw std::invalid_argument("invalid hash"); @@ -154,18 +159,25 @@ cartesi::machine_merkle_tree::hash_type convert_from_c(const cm_hash *c_hash) { // The C API implementation // ---------------------------------------------- -cm_error cm_new(const cm_machine *m, cm_machine **new_m) try { +cm_error cm_new(cm_machine **new_m) try { if (new_m == nullptr) { throw std::invalid_argument("invalid new machine output"); } - if (m == nullptr) { - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) - *new_m = reinterpret_cast(new cartesi::virtual_machine()); - } else { - const auto *cpp_m = convert_from_c(m); - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) - *new_m = reinterpret_cast(cpp_m->clone_empty()); + *new_m = convert_to_c(new cartesi::virtual_machine()); + return cm_result_success(); +} catch (...) { + if (new_m != nullptr) { + *new_m = nullptr; + } + return cm_result_failure(); +} + +cm_error cm_clone_empty(const cm_machine *m, cm_machine **new_m) try { + if (new_m == nullptr) { + throw std::invalid_argument("invalid new machine output"); } + const auto *cpp_m = convert_from_c(m); + *new_m = convert_to_c(cpp_m->clone_empty()); return cm_result_success(); } catch (...) { if (new_m != nullptr) { @@ -217,7 +229,7 @@ cm_error cm_load(cm_machine *m, const char *dir, const char *runtime_config) try } cm_error cm_load_new(const char *dir, const char *runtime_config, cm_machine **new_m) { - auto err = cm_new(nullptr, new_m); + auto err = cm_new(new_m); if (err != 0) { return err; } @@ -230,7 +242,7 @@ cm_error cm_load_new(const char *dir, const char *runtime_config, cm_machine **n } cm_error cm_create_new(const char *config, const char *runtime_config, cm_machine **new_m) { - auto err = cm_new(nullptr, new_m); + auto err = cm_new(new_m); if (err != 0) { return err; } diff --git a/src/machine-c-api.h b/src/machine-c-api.h index c9b2b955..54101151 100644 --- a/src/machine-c-api.h +++ b/src/machine-c-api.h @@ -333,18 +333,27 @@ CM_API cm_error cm_get_reg_address(const cm_machine *m, cm_reg reg, uint64_t *va // Machine API functions // ----------------------------------------------------------------------------- -/// \brief Creates a new machine object. -/// \param m Pointer to the existing machine object (can be NULL). +/// \brief Creates a new local machine object. +/// \param new_m Receives the pointer to the new machine object. Set to NULL on failure. +/// \returns 0 for success, non zero code for error. +/// \detail A newly created object is empty (does not hold a machine instance). +/// Use cm_create() or cm_load() to instantiate a machine into the object. +/// Use cm_create_new() or cm_load_new() as single-call shortcuts. +/// Use cm_delete() to delete the object. +CM_API cm_error cm_new(cm_machine **new_m); + +/// \brief Clones empty machine object from existing one. +/// \param m Pointer to the existing machine object to clone from. /// \param new_m Receives the pointer to the new machine object. Set to NULL on failure. /// \returns 0 for success, non zero code for error. -/// \details If the parameter \p m is not NULL, the new machine object will be of -/// the same type. Otherwise, it will be a local machine. +/// \details The new machine object will be of the same type as \p m. +/// Local if \p m is local, remote on the same host if \p is remote. /// Regardless, a newly created object is empty (does not hold a machine instance). /// Use cm_create() or cm_load() to instantiate a machine into the object. /// Use cm_delete() to delete the object. -CM_API cm_error cm_new(const cm_machine *m, cm_machine **new_m); +CM_API cm_error cm_clone_empty(const cm_machine *m, cm_machine **new_m); -/// \brief Checks if object is empty (does not holds a machine instance). +/// \brief Checks if object is empty (does not hold a machine instance). /// \param m Pointer to the existing machine object. /// \param yes Receives true if empty, false otherwise. /// \returns 0 for success, non zero code for error.