aboutsummaryrefslogtreecommitdiffstats
path: root/core/module-run.h
diff options
context:
space:
mode:
Diffstat (limited to 'core/module-run.h')
-rw-r--r--core/module-run.h94
1 files changed, 94 insertions, 0 deletions
diff --git a/core/module-run.h b/core/module-run.h
new file mode 100644
index 0000000..49bdf35
--- /dev/null
+++ b/core/module-run.h
@@ -0,0 +1,94 @@
+#ifndef PURE_MODULE_RUN_H
+#define PURE_MODULE_RUN_H
+/* How a block runs, shared by the executor (module.c) and the compiled code
+ * (module-jit.c): their frame, and the steps the compiled code calls. Not a
+ * public interface. */
+#include "module.h"
+
+/* An item's or a key's op->plan: its cell a text; a FIND joined to the ITEM_GET after it. */
+enum { PLAN_TEXT = 1, PLAN_JOINED = 2 };
+
+typedef struct { union { double num; int64_t i64; }; PureBytes bytes; } Slot;
+
+/* A walk (EACH): the list, the item it runs for, where it ends (items the
+ * walk removes move it), and whether that item left. */
+typedef struct { uint32_t list; size_t at, end; bool removed; } Walk;
+/* A loop that runs in its block's run (LOOP, EACH): its block and where
+ * the code around it ends, the arena as it began, a walk's walk and the
+ * event's walk and row around it, a count's values (low + k of count) and
+ * slot. */
+typedef struct {
+ uint32_t start, end, outer;
+ size_t mark;
+ bool walking, integer;
+ Walk walk, *around;
+ size_t row;
+ uint64_t count, k;
+ PureValue low, *slot;
+} Loop;
+typedef struct {
+ PureApp *app;
+ const PureInputShape *shape; /* message, or NULL */
+ const char *key; /* a keyed message's key */
+ int64_t base; /* the revision a message's edit was made against, or -1 */
+ PureArena *arena;
+ double dt;
+ size_t row; /* the row a column is evaluated for (in a fold, the fold's item) */
+ size_t outer; /* in a fold, the row of the column it runs in */
+ Walk *walk; /* the walk the code runs in, or NULL */
+ PureValue *locals; /* the event's locals (a handler's, and what runs in it), or NULL */
+ bool arguments; /* FIELD reads the arguments given for a view, not the message */
+ bool modified, exists;
+ uint32_t (*spans)[2]; /* a message's variable fields: start and size in the payload */
+} Event;
+
+/* ---- Running a block (docs/design/021). A frame holds what a block reads
+ * and changes as it runs: its operand stack and the loops open in it. step
+ * runs one instruction but a branch or a loop's; run takes those itself, as
+ * the compiled code does (module-jit.c), so both run the same steps. */
+typedef struct {
+ const PureModule *m;
+ PureValue *values;
+ Event *ev;
+ PureApp *app;
+ PureArena *arena;
+ Slot *stack;
+ size_t sp;
+ uint32_t end; /* where the innermost loop's block ends, or the block's */
+ unsigned depth; /* the loops open */
+ PureFault kind; /* a fault's */
+ PureResult status; /* what refused or stopped it */
+ uint32_t fault_pc; /* the instruction that faulted or refused */
+ Loop *loops; /* PURE_MODULE_NESTING of them, apart: a walk points into its loop */
+} Frame;
+
+/* How a step went: on to the next instruction; a fault (kind at fault_pc);
+ * refused (status: past a limit or nothing found is a fault there, else it
+ * is returned); stopped (status returned as it is). */
+enum { STEP_NEXT, STEP_FAULT, STEP_REFUSED, STEP_RETURN };
+
+/* The instruction after op at pc: past a fold's block, or the ITEM_GET a FIND was joined to. */
+static inline uint32_t after(const PureOp *op, uint32_t pc) {
+ return op->op == PURE_OP_FOLD ? pc + 1 + (op->arg >> 16) : pc + 1 + (op->op == PURE_OP_LIST_FIND && op->plan & PLAN_JOINED);
+}
+
+/* The steps compiled code takes from the executor (module.c): an
+ * instruction but a branch or a loop's (how; the next is after()); a walk or
+ * a loop opened at pc (STEP_NEXT: its block next, STEP_SKIP: none, past its
+ * block); BREAK; a loop's block ran once (STEP_NEXT: again, STEP_DONE: the
+ * loop ended). */
+enum { STEP_SKIP = 4, STEP_DONE = 5 };
+int pure_run_step(Frame *, uint32_t pc);
+int pure_run_each(Frame *, uint32_t pc);
+int pure_run_loop(Frame *, uint32_t pc);
+void pure_run_break(Frame *);
+int pure_run_iterate(Frame *);
+
+/* A module's code compiled (AArch64 Linux; elsewhere, or with PURE_JIT=0 in
+ * the environment, none): a block's code runs a frame as run does, giving how
+ * it went (a STEP_). */
+typedef int (*PureCompiled)(Frame *);
+struct PureJit *pure_jit_make(const PureModule *);
+void pure_jit_free(struct PureJit *);
+PureCompiled pure_jit_code(const struct PureJit *, PureBlock);
+#endif