diff options
| author | eunhhu <[email protected]> | 2026-09-24 17:14:54 +0100 |
|---|---|---|
| committer | eunhhu <[email protected]> | 2026-09-24 17:14:54 +0100 |
| commit | b1ce1927022d374198441afafeb27199fc8a052a (patch) | |
| tree | 6021f175f4c67ed03b44240eaa2f90d846f12f6f /prototypes/connections/evaluate.c | |
| parent | d34f9426d5317a1948f12f229439946728bc342a (diff) | |
| download | pure-b1ce1927022d374198441afafeb27199fc8a052a.tar.gz pure-b1ce1927022d374198441afafeb27199fc8a052a.zip | |
Establish native micro runtime checkpoint
Diffstat (limited to 'prototypes/connections/evaluate.c')
| -rw-r--r-- | prototypes/connections/evaluate.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/prototypes/connections/evaluate.c b/prototypes/connections/evaluate.c new file mode 100644 index 0000000..88ffae7 --- /dev/null +++ b/prototypes/connections/evaluate.c @@ -0,0 +1,53 @@ +#include "program.h" +#include <stdint.h> + +bool pure_region_span(PureRegion region, PureSpan source, PureSpan *out) { + *out = (PureSpan){0}; + if (region.offset > source.size) return false; + size_t length = region.to_end ? source.size - region.offset : region.length; + if (length > source.size - region.offset) return false; + *out = (PureSpan){length ? source.data + region.offset : NULL, length}; + return true; +} + +static bool index_read(PureIndex index, PureSpan source, size_t *out) { + if (!index.from_u32le) { *out = index.value; return true; } + if (index.value > source.size || 4 > source.size - index.value) return false; + const unsigned char *bytes = source.data + index.value; + *out = (size_t)bytes[0] | (size_t)bytes[1] << 8 | (size_t)bytes[2] << 16 | (size_t)bytes[3] << 24; + return true; +} + +bool pure_program_splice(const PureProgram *p, PureSpan source, size_t *offset, size_t *remove) { + return p->splice && index_read(p->splice_offset, source, offset) && + index_read(p->splice_remove, source, remove); +} + +static bool resolve(PureRegion region, size_t step, PureSpan source, + const PureSpan *values, size_t count, PureSpan *out) { + if (!step) return pure_region_span(region, source, out); + if (step > count) return false; + *out = values[step - 1]; + return true; +} + +bool pure_program_input(const PureProgram *p, PureSpan source, PureSpan *write, PureSpan *reply) { + *write = (PureSpan){0}; + *reply = (PureSpan){0}; + if (source.size < p->input_required || p->input_steps > PURE_DYNAMIC_LIMIT) return false; + PureSpan values[PURE_DYNAMIC_LIMIT]; + for (size_t i = 0; i < p->input_steps; ++i) { + const PureRangeStep *step = &p->steps[i]; + PureSpan parent; + size_t offset, length; + if (!resolve(step->source, step->source_step, source, values, i, &parent) || + !index_read(step->offset, source, &offset) || !index_read(step->length, source, &length) || + !pure_region_span((PureRegion){.offset = offset, .length = length}, parent, &values[i])) return false; + } + PureSpan stored, returned = {0}; + if (!resolve(p->write, p->write_step, source, values, p->input_steps, &stored) || + (p->reply_input && !resolve(p->reply, p->reply_step, source, values, p->input_steps, &returned))) return false; + *write = stored; + *reply = returned; + return true; +} |
