Fix documentation

This commit is contained in:
alejo committed 2026-09-25 03:20:35 -03:00
1 parent a317c07124
commit ab21b3f30d
27 files changed
+2137 -1043

No files matched your search

@@ -1,47 +1,88 @@
/* CppWidgetApi.h -- a C++ (not extern "C") surface living alongside
/**
* @file CppWidgetApi.h
* @brief A C++ (not extern "C") surface living alongside
* PluginApi.h's plain C one, in the SAME plugin build. Every member
* function below keeps its real, compiler-mangled name; nothing here
* needs special handling by source/HotReload, which classifies
* symbols by their type and section, never by what their name looks
* like -- see hot_reload.h's "REQUIREMENTS ON A HOT-RELOADABLE
* MODULE" and README.md's "Hot reloading C++ symbols" for the full
* picture.
* like -- see the "Requirements on a hot-reloadable module" section of
* hot_reload.h and the "Hot reloading C++ symbols" section of
* source/HotReload/README.md for the full picture.
*
* The two methods below are reached two different ways from
* Host/Main.cpp, deliberately: see that file's comments for why.
*/
#pragma once
/**
* @brief A small C++ class whose members are defined in the plugin, not the host.
*
* Each member below keeps its real, compiler-mangled name and is reached a different way from
* Host/Main.cpp -- through the vtable, through a manually resolved mangled name, and (for the
* operator) not at all -- to show that all of them patch like any plain C function.
*/
class CppWidget
{
public:
/**
* @brief Virtual, so that destroying a widget through a base pointer works across the
* boundary.
*/
virtual ~CppWidget() = default;
/* Virtual: Host/Main.cpp calls this through ordinary C++
/**
* @brief Scales its input, through a virtual call.
*
* Virtual: Host/Main.cpp calls this through ordinary C++
* polymorphic dispatch (widget->virtualTick(x)) and needs no
* manual symbol lookup at all -- the call compiles down to an
* indirect call through the object's vtable slot, not a direct
* reference to this specific symbol, so it needs no link-time
* dependency on whichever plugin build actually defines it. */
* dependency on whichever plugin build actually defines it.
*
* @param input The value to scale.
* @return V1: `input * 2`. V2: `input * 3`.
*/
virtual int virtualTick(int input);
/* An ordinary out-of-line method. Calling this as widget->tick(x)
/**
* @brief Scales its input, through an ordinary out-of-line method.
*
* Calling this as widget->tick(x)
* would compile to a direct call to CppWidget::tick's own mangled
* symbol, which would need the Host to link against a plugin
* build at build time -- exactly what hot-reloading a plugin
* means avoiding. So Host/Main.cpp instead resolves it manually
* by its mangled name via hot_reload_get_symbol(), the same way
* it resolves PluginApi.h's plain C functions. */
* it resolves PluginApi.h's plain C functions.
*
* @param input The value to scale.
* @return V1: `input * 2`. V2: `input * 3`.
*/
int tick(int input);
/* An overloaded operator: mechanically just a function with an
/**
* @brief An overloaded operator.
*
* Mechanically just a function with an
* unusual mangled name, reached the same manual way as tick()
* above. */
* above.
*
* @param other Ignored; the operator only prints which build it is.
* @return A new, empty widget.
*/
CppWidget operator+(const CppWidget& other) const;
};
/* The one entry point Host/Main.cpp looks up by a plain, human-typed
/**
* @brief Creates a widget.
*
* The one entry point Host/Main.cpp looks up by a plain, human-typed
* name -- extern "C" here for exactly the reason hot_reload.h
* recommends it: something to hand a human-readable name to, without
* needing to know or hardcode a mangled string. */
* needing to know or hardcode a mangled string.
*
* @return A new widget. The caller owns it and must `delete` it (safe across the plugin
* boundary here because host and plugin share one C++ runtime and allocator).
*/
extern "C" CppWidget* make_cpp_widget();
@@ -1,4 +1,6 @@
/* PluginApi.h -- the contract PluginV1 and PluginV2 both implement,
/**
* @file PluginApi.h
* @brief The contract PluginV1 and PluginV2 both implement,
* and the Host loads by name. Every function here follows
* cpp-style-guide.md section 11's rule for anything loaded at runtime:
* plain C linkage, no classes or exceptions crossing the boundary.
@@ -15,31 +17,64 @@ extern "C"
{
#endif
/* Changes behavior between V1 and V2 -- watch this one get
* HOT_RELOAD_SYMBOL_PATCHED. */
/**
* @brief Scales its input, and prints which build it is.
*
* Changes behavior between V1 and V2 -- watch this one get
* HOT_RELOAD_SYMBOL_PATCHED.
*
* @param input The value to scale.
* @return V1: `input * 2`. V2: `input * 3`.
*/
int plugin_tick(int input);
/* Only in V1, gone in V2 -- watch this one get
* HOT_RELOAD_SYMBOL_REMOVED, and the Host's stub take over for any
* call still aimed at it afterwards. */
/**
* @brief A feature that exists only in V1.
*
* Gone in V2 -- watch this one get HOT_RELOAD_SYMBOL_REMOVED, and the
* Host's stub take over for any call still aimed at it afterwards.
*
* @param input The value to echo.
* @return @p input, unchanged.
*/
int plugin_legacy_feature(int input);
/* Only in V2 -- watch this one get HOT_RELOAD_SYMBOL_ADDED, then
* get called for the first time right after. */
/**
* @brief A feature that exists only in V2.
*
* Watch this one get HOT_RELOAD_SYMBOL_ADDED, then get called for the
* first time right after.
*
* @param input The value to scale.
* @return `input * 10`.
*/
int plugin_new_feature(int input);
#if defined(__GNUC__) || defined(__clang__)
/* Deliberately too small to safely hold a jump on any of this
* library's backends (its patchable-function-entry padding is
* overridden down to zero) -- watch this one get
* HOT_RELOAD_SYMBOL_SKIPPED_TOO_SMALL rather than corrupt whatever
* comes after it. MSVC has no equivalent per-function override
* this demo could apply, so this one only exists on GCC/Clang.
/**
* @brief An empty function, too small to hold the jump this library writes.
*
* Its patchable-function-entry padding is overridden down to zero, so
* all that is left is the compiled empty body -- a handful of bytes,
* fewer than the jump any of this library's backends writes on x86-64
* and ARM64 at any optimization level. Watch this one get
* HOT_RELOAD_SYMBOL_SKIPPED_TOO_SMALL rather than corrupt whatever comes
* after it.
*
* Two configurations cannot promise "too small": unoptimized 32-bit x86
* (its jump is only 5 bytes, which even an empty unoptimized function
* reaches), and Windows, where a PE image carries no per-function size
* and the library can only estimate one from the distance to the next
* export. MSVC has no equivalent per-function override this demo could
* apply, so this one only exists on GCC/Clang.
*/
__attribute__((patchable_function_entry(0))) int plugin_tiny_function(int input);
__attribute__((patchable_function_entry(0))) void plugin_tiny_function(void);
#endif
/* An exported VARIABLE, not a function, sitting right next to
/**
* @brief The build's version number: 1 in V1, 2 in V2.
*
* An exported VARIABLE, not a function, sitting right next to
* real functions in the same library and changing value between
* V1 and V2 just like plugin_tick's behavior does -- watch this
* one get HOT_RELOAD_SYMBOL_SKIPPED_NOT_CODE. This is the