diff --git a/docs/ABI.md b/docs/ABI.md new file mode 100644 index 0000000..3455c05 --- /dev/null +++ b/docs/ABI.md @@ -0,0 +1,81 @@ +# ABI + +## Value ABI + +At its core, the Giterated Runtime uses the `extern "C"` ABI. What that means is likely platform specific, and doesn't matter. +You are intended to compile the Giterated Runtime and Plugins for your local machine, all with a similar idea of what +your "local machine" is. + +Values are passed using the `FFI` type. There are four categories of value that the `FFI` type enables you to pass: + +| `FFI` Type Category | Placed Backing? | Owned? | +|---------------------|-----------------|--------| +| Slice | Heap/Stack | No | +| Referenced Slice | Stack | No | +| Referenced Value | No | No | +| Owned Value | Heap | Yes | + +For an FFI type to have a "placed backing" is for it to have some data structure beyond the data it represents, placed +somewhere in memory. Some types only require stack placement while some offer both stack and heap placement. + +Stack-placed values can be shared by `PinnedRef` and `PinnedMut`, and thus can only be owned by the caller. + +Heap-placed values can be shared by `Owned`, `PinnedRef`, and `PinnedMut`. They can be owned by any one consumer, +When the handle with ownership is `Drop`'d by the sole consumer, it will free the object using the associated `Drop` callback. + +### Safety Intents + +This API is designed to simplify interaction with FFI values, and provide a static ABI for those values to be passed. It +is key to enabling ownership across FFI while ensuring associated dropping and allocation freeing logic is ran. + +The contract the developer has to follow is made simpler by this system, and it allows for generic code to be written to +interact with FFI-given values and pass values using FFI. + +### Stability Guarantees + +There are no plans to guarantee stability until 1.0.0. At that point you can expect the ABI to remain stable until the major version +is incremented again. There will be an appropriate deprecation process and changeover period. + +### Memory Representation + +Please check out the source code, sorry if you needed that from the docs! + +## Object, Operation, Setting, Value, Plugin, and Runtime ABIs + +The Giterated Runtime uses vtables to accomplish the goal of ensuring maximum compatibility. For every object that is shared +between plugins, a vtable is used to allow each plugin to provide their own code for interacting with the object. + +When objects switch "runtime domains" (e.g. host -> plugin, plugin -> plugin, plugin -> host), their vtable is swapped out +for the new runtime domain's own vtables. + +### Untyped "Objects" (see above header for list) + +Untyped objects, in memory, are represented by a data pointer and a vtable pointer. Exactly like Rust traits. However, to +prevent small compilation differences and other random garbage from making the interface not perfectly compatible we use +the local plugin's idea of the vtable for the object at all times. An object that the plugin does not have a vtable for cannot +be relevant to the plugin. + +It is important that the object's base representation in memory remain unchanged between major versions, but the vtables that provide methods for +that object may be grown. The methods that operate on that object may be changed in an non-breaking fashion, and bugs can be +fixed. + +## Futures ABI + +The Giterated Runtime has an async runtime that allows for futures to be shared and awaited across FFI boundaries while only +executing the future within the context of the Plugin who is running the underlying future. + +Futures are spawned onto the `RuntimeState` with the `RuntimeFuturesExt` trait. This takes a Rust future, boxes it, and +provides a `RuntimeFuture` handle that can be used to drive the underlying Rust future locally. The `RuntimeFuture` handle +is thread-safe and can be shared with the callee and `.await`'d directly like any other future. + +### RuntimeFuture + +The `RuntimeFuture` mixes a vtable with data to allow for any caller to drive a spawned future. It contains: + +- A `poll_fn` which is used to poll the future for `Ready`-ness +- A `wake_fn` which is used to wake the callee to poll for (expected) `Ready`-ness, it is populated when the `RuntimeFuture` is `await`'d. + +When the `RuntimeFuture` is polled, it causes the inner future to also be polled. We provide the inner future with a waker +that triggers the `RuntimeFuture`'s waker so it is polled again. Breaking character to point out how freaking cool that is. + +`RuntimeFuture`s drop the associated inner future as they drop. \ No newline at end of file diff --git a/docs/PLUGINS.md b/docs/PLUGINS.md new file mode 100644 index 0000000..a1806b7 --- /dev/null +++ b/docs/PLUGINS.md @@ -0,0 +1,14 @@ +# Plugins + +The Giterated Runtime does nothing on its own. Plugins are what bring functionality and logic which the Runtime executes. + +Plugins can be written in any language that can be compatible with the ABI and API set by the Giterated Runtime. There is no +hard requirement that the plugins need to be developed with Rust, but as of the time of writing this document that is the only +intended first-party supported language on the roadmap. The design seems relatively friendly for other languages to meet. + +## [The ABI](ABI.md) + +## The API + +The Giterated Runtime uses a set of standard function identifiers which it attempts to dynamically resolve from the Plugin's +binary. \ No newline at end of file