diff options
Diffstat (limited to 'core/module-run.h')
| -rw-r--r-- | core/module-run.h | 94 |
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 |
