aboutsummaryrefslogtreecommitdiffstats
path: root/core/module.h
diff options
context:
space:
mode:
Diffstat (limited to 'core/module.h')
-rw-r--r--core/module.h81
1 files changed, 23 insertions, 58 deletions
diff --git a/core/module.h b/core/module.h
index d23cb49..d155b41 100644
--- a/core/module.h
+++ b/core/module.h
@@ -8,7 +8,7 @@
#include <stddef.h>
#include <stdint.h>
-/* Pure module format v6 (docs/design/008-module-format.md). A toolchain such
+/* Pure module format v7 (docs/design/008-module-format.md). A toolchain such
* as aup produces it; Pure verifies it completely before anything executes:
* operand types (including which text a cursor and which list an index
* belongs to), stack heights and the stack at every join, forward-only
@@ -16,10 +16,10 @@
enum {
PURE_MODULE_STATES = 32, PURE_MODULE_INPUTS = 32, PURE_MODULE_VIEWS = 64,
PURE_MODULE_HANDLERS = 64, PURE_MODULE_CODE = 65535, PURE_MODULE_STACK = 64,
- PURE_MODULE_NAME = 32, PURE_MODULE_STRINGS = 32768, PURE_MODULE_HEADER = 40,
- PURE_MODULE_FIELDS = 64, PURE_MODULE_COLLECTIONS = 1, PURE_MODULE_CONSTANTS = 4096,
+ PURE_MODULE_NAME = 32, PURE_MODULE_STRINGS = 32768, PURE_MODULE_HEADER = 38,
+ PURE_MODULE_FIELDS = 64, PURE_MODULE_CONSTANTS = 4096,
PURE_MODULE_CONSTANT_BYTES = 1 << 20, PURE_MODULE_RECORDS = 16, PURE_MODULE_RECORD_FIELDS = 128,
- PURE_RECORD_FIELDS = 16, PURE_MODULE_JOINS = 8, PURE_APP_PENDING = 256
+ PURE_RECORD_FIELDS = 16, PURE_MODULE_JOINS = 8
};
typedef enum {
@@ -27,7 +27,7 @@ typedef enum {
PURE_OP_DIV, PURE_OP_NEG, PURE_OP_LT, PURE_OP_LE, PURE_OP_GT, PURE_OP_GE,
PURE_OP_EQ, PURE_OP_NE, PURE_OP_AND, PURE_OP_OR, PURE_OP_NOT, PURE_OP_MIN,
PURE_OP_MAX, PURE_OP_CLAMP, PURE_OP_STORE, PURE_OP_JZ, PURE_OP_JMP,
- PURE_OP_FIELD, PURE_OP_DOC, PURE_OP_DOC_SIZE, PURE_OP_LEN, PURE_OP_REPLACE,
+ PURE_OP_FIELD, PURE_OP_LEN,
PURE_OP_REPLY, PURE_OP_REQUIRE,
PURE_OP_TEXT_CONST, PURE_OP_TEXT_LOAD, PURE_OP_TEXT_INPUT, PURE_OP_NUM_TEXT,
PURE_OP_CONCAT, PURE_OP_CHARS, PURE_OP_LINES, PURE_OP_TEXT_BYTES,
@@ -126,8 +126,8 @@ enum { PURE_FORMAT_WIDTH = 8, PURE_FORMAT_ZEROS = 1 << 16, PURE_FORMAT_FORM = 17
* locals (0 as it begins), and its own of what the function's code names:
* values held by name (empty), an event's lists (empty) and registers (bound
* to none); the caller's are as they were when the call returns. A function
- * runs as a handler's code does but for a message (no field, document or
- * reply); a handler and the functions run CALL (not a view), and a walk around
+ * runs as a handler's code does but for a message (no field or reply); a
+ * handler and the functions run CALL (not a view), and a walk around
* a call keeps to what the callee changes as it keeps to its own block's
* changes. Calls nest as deep as the event's room allows: each counts its
* frame's bytes there (MEMORY past it) and its block's length as work.
@@ -308,7 +308,6 @@ typedef struct {
typedef struct { char name[PURE_MODULE_NAME]; uint8_t type; uint16_t rows; uint32_t offset; } PureField;
typedef struct {
uint8_t kind;
- bool keyed;
uint16_t field_start, field_count;
uint32_t prefix; /* fixed payload bytes before the variable fields */
uint32_t period; /* a timer's, in milliseconds */
@@ -339,12 +338,11 @@ typedef struct { uint8_t lower_relation, upper_relation; PureBlock lower, upper;
_Static_assert(PURE_MODULE_STATES <= 32, "a state is a bit of PureApp.counted");
typedef struct {
- uint16_t states, inputs, views, handlers, fields, collections, constants, records, record_fields;
+ uint16_t states, inputs, views, handlers, fields, constants, records, record_fields;
uint32_t code_count;
char state_names[PURE_MODULE_STATES][PURE_MODULE_NAME];
char input_names[PURE_MODULE_INPUTS][PURE_MODULE_NAME];
char view_names[PURE_MODULE_VIEWS][PURE_MODULE_NAME];
- char collection_names[PURE_MODULE_COLLECTIONS][PURE_MODULE_NAME];
char input_keys[PURE_MODULE_INPUTS][PURE_MODULE_NAME];
uint8_t state_type[PURE_MODULE_STATES];
uint16_t state_ref[PURE_MODULE_STATES]; /* text: constant; cursor: text; list: record; index: list */
@@ -449,27 +447,13 @@ int pure_module_position(const PureModule *, uint32_t view);
* state), or -1: a host may lend its stored extents instead of copying. */
int pure_module_text_state(const PureModule *, uint32_t view);
-/* Keyed collections live in a data host (for example the tree store). One
- * event opens at most one document, the message's key, at its current
- * version; edits stay in that working version until the event commits it.
- * A version's bytes field is the value's size. */
+/* A data host keeps the app's states (for example the tree store); without one (all of it NULL) they live in memory
+ * alone. state opens a runtime-owned value by name as a draft (a missing one is empty at revision 0); save publishes
+ * the given drafts together, all or nothing. */
typedef struct {
void *context;
- PureResult (*open)(void *context, uint32_t collection, const char *key,
- void **document, int64_t *revision);
- PureVersion (*version)(void *context, void *document);
- PureResult (*read)(void *context, void *document, PureVersion, size_t offset, size_t length,
- bool (*visit)(void *, PureSpan), void *visit_context);
- PureResult (*splice)(void *context, void *document, size_t offset, size_t remove, PureSpan insert);
- PureResult (*commit)(void *context, void *document, int64_t *revision);
- void (*close)(void *context, void *document);
- /* Optional: the host keeps the app's states. state opens a runtime-owned
- * value by name as a draft (a missing one is empty at revision 0); save
- * publishes the given documents and state drafts together, all or
- * nothing, and names each document's new revision. */
PureResult (*state)(void *context, const char *name, PureDraft **out);
- PureResult (*save)(void *context, void *const *documents, size_t document_count, PureDraft *const *states,
- size_t count, int64_t *revisions);
+ PureResult (*save)(void *context, PureDraft *const *states, size_t count);
/* Optional, with state and save: the directory where the app's lists are
* kept, their images and the log of their changes (core/log.h); without
* one, list states are not stored. */
@@ -477,7 +461,7 @@ typedef struct {
} PureData;
/* A byte or text value inside one event or view: a range of the payload, a
- * document or text version, a module constant, a copy or the event's arena. */
+ * text version, a module constant, a copy or the event's arena. */
typedef struct { uint8_t source; uint16_t owner; PureVersion version; uint64_t offset, length; } PureBytes;
typedef struct { unsigned char *bytes; size_t used, capacity; } PureArena;
@@ -487,13 +471,11 @@ typedef struct { unsigned char *bytes; size_t used, capacity; } PureArena;
* (or 0 in an empty list). Every event is atomic: on failure nothing changes.
*
* Saving. When the data host keeps states the app starts from the stored
- * ones. A save publishes, in one commit, the documents edited by messages and
- * the states changed since the last save; if it fails, every event since the
- * last save is undone. By default each key, text and message event saves
- * before it returns (a frame waits for the next one). Deferred, events apply
- * at once and a host saves a burst with one commit: an event is durable once
- * a later save succeeds, and each key's document joins a burst once (a second
- * message for it, or one past PURE_APP_PENDING keys, saves the burst first). */
+ * ones. A save publishes, in one commit, the states changed since the last
+ * save; if it fails, every event since the last save is undone. By default
+ * each key, text and message event saves before it returns (a frame waits for
+ * the next one). Deferred, events apply at once and a host saves a burst with
+ * one commit: an event is durable once a later save succeeds. */
/* The runtime's lists' places among the stored lists' records (PureApp):
* the numbers heard, and the outbox. */
enum { PURE_LIST_HEARD = PURE_MODULE_STATES, PURE_LIST_OUTBOX, PURE_LISTS_STORED };
@@ -521,20 +503,12 @@ typedef struct {
bool uncertain; /* a save may or may not be stored: none follows until a start */
PureDraft *stored_values; /* numbers, cursors and indices, when kept */
PureVersion saved[PURE_MODULE_STATES]; /* text and list versions at the last save */
- /* Events since the last save: what a failed save returns to, and the
- * documents messages opened (held until the save). */
+ /* Events since the last save: what a failed save returns to. */
bool deferred, open;
PureValue durable_values[PURE_MODULE_STATES];
PureVersion durable_texts[PURE_MODULE_STATES];
size_t durable_lists[PURE_MODULE_STATES]; /* each stored list's journal length */
uint64_t durable_ticks, durable_events;
- struct PurePending { void *document; char key[65]; bool edited; } *pending; /* grows to PURE_APP_PENDING */
- unsigned pending_count, pending_capacity;
- /* The pending documents by key, so a message finds its key in one look:
- * open addressing over the key's hash, a slot holding one more than the
- * document's place in pending (0: none). */
- uint16_t pending_index[2 * PURE_APP_PENDING];
- bool document_pending; /* the current event's document is among them */
PureFault fault;
uint32_t fault_pc;
size_t memory; /* the budget of what the states hold (0: none): pure_app_memory */
@@ -553,12 +527,10 @@ typedef struct {
struct PureRows { uint32_t table; uint64_t changes, given; size_t *items, count, capacity; PureFault fault; } *rows; /* a filtered table's items */
unsigned row_tables;
/* Current message or text event, kept until pure_app_finish. */
- void *document;
PureSpan payload;
bool has_reply;
PureBytes reply;
unsigned char *copied;
- int64_t revision;
PureArena arena, view_arena;
/* Links (runtime-owned, saved with the states): the outbox, messages sent
* on outputs and not trimmed, in the order sent, a list of {output (its
@@ -612,11 +584,8 @@ PureResult pure_app_start(PureApp *, const PureModule *, PureData data);
/* Publish every change since the last save in one commit, or undo them all. */
PureResult pure_app_save(PureApp *);
/* Defer saving to pure_app_save (false: save after each event). Needs a data
- * host that saves documents together (PureData.save). */
+ * host that saves together (PureData.save). */
bool pure_app_defer(PureApp *, bool deferred);
-/* Whether key's document is in the unsaved burst: a message for it would
- * save the burst first. */
-bool pure_app_pending(const PureApp *, const char *key);
/* Leaves unsaved frame changes unsaved: call pure_app_save first to keep them. */
void pure_app_stop(PureApp *);
PureResult pure_app_frame(PureApp *);
@@ -629,18 +598,14 @@ PureResult pure_app_input(PureApp *, uint32_t input, PureEdge);
PureResult pure_app_point(PureApp *, uint32_t state, size_t position);
/* Deliver committed text (for example from an input method). Not UTF-8: invalid. */
PureResult pure_app_text(PureApp *, uint32_t input, PureSpan text);
-/* Deliver a message. base is the revision the sender edited, or -1 for none;
- * a handler that edits the document needs one. payload stays alive until
- * pure_app_finish. On return app->revision is the document's revision
- * (deferred: the revision the next save gives it). */
-PureResult pure_app_message(PureApp *, uint32_t input, const char *key, int64_t base, PureSpan payload);
+/* Deliver a message. payload stays alive until pure_app_finish. */
+PureResult pure_app_message(PureApp *, uint32_t input, PureSpan payload);
/* The same, with the variable fields where the host found them: field f
* starts at placed[2f] in payload and has placed[2f + 1] bytes (entries of
* fixed fields are not read, nor are the variable fields' lengths in the
* prefix). A host that parsed a request in place passes the fields' bytes
* where they are. */
-PureResult pure_app_message_fields(PureApp *, uint32_t input, const char *key, int64_t base, PureSpan payload,
- const uint32_t *placed);
+PureResult pure_app_message_fields(PureApp *, uint32_t input, PureSpan payload, const uint32_t *placed);
/* Visit the reply of the last message in order, without copying, until the
* next event (deferred: copy it before a later save too). */
PureResult pure_app_reply(const PureApp *, bool (*visit)(void *, PureSpan), void *context);