diff options
| author | eunhhu <[email protected]> | 2026-10-19 00:16:56 +0100 |
|---|---|---|
| committer | eunhhu <[email protected]> | 2026-10-19 00:16:56 +0100 |
| commit | 3cc6bc3d8a1d8827519decbf7e084e89110c93f9 (patch) | |
| tree | eb2aa0a0df93815a562e270696b6de3717198c0f /core/module.c | |
| parent | d7caf4dfb1947d8f804e3d8ae7ef066c6e3b8fb7 (diff) | |
| download | pure-3cc6bc3d8a1d8827519decbf7e084e89110c93f9.tar.gz pure-3cc6bc3d8a1d8827519decbf7e084e89110c93f9.zip | |
027's 4f-3b: no fixed count of records or of their fields in all: the header's u16s alone (16 and 128 before); a stored list's record graph (PureLayout) holds a few records itself and more on the heap, 256 at most (an image numbers them in a byte), an image or a checkpoint not written then without room for it; a record's 16 fields kept, the list engine's width (a leaf's columns, a run's columns and narrow cells, the arrays' and packs' columns), to be widened with the lists' shapes sized to their fields; unit tests: 20 records of 10 fields (200 in all), an item of the last appended; a stored list whose six records each hold a list of the next saved and read back after a restart (its graph on the heap); counts: b41 against b40 with batches BFS +0.12%, without BFS -0.09%, the rest within 0.001%; the bank's queries (s40 and s41 in turns, six each) within 0.09% (the first three's in_credit +1.16% its spread: 2.75% between runs of one build); 008 and 027
Diffstat (limited to 'core/module.c')
| -rw-r--r-- | core/module.c | 40 |
1 files changed, 34 insertions, 6 deletions
diff --git a/core/module.c b/core/module.c index ba44a85..3d38966 100644 --- a/core/module.c +++ b/core/module.c @@ -1712,7 +1712,6 @@ PURE_COLD PureResult pure_module_load(const void *bytes, size_t size, PureModule out->state_words = (uint16_t)((out->states + 63) / 64 + !out->states); if (out->code_count > PURE_MODULE_CODE || strings > PURE_MODULE_STRINGS || out->constants > PURE_MODULE_CONSTANTS || constant_bytes > PURE_MODULE_CONSTANT_BYTES || - out->records > PURE_MODULE_RECORDS || out->record_fields > PURE_MODULE_RECORD_FIELDS || out->functions > PURE_MODULE_FUNCTIONS) { result = PURE_LIMIT; REFUSE("module exceeds a limit", 8); @@ -5998,7 +5997,33 @@ static uint8_t cell_kind(const PureModule *m, uint32_t field, bool kept) { /* Whether a stored kind's cell is bytes in the stored form: a text's, or a list's. */ static bool stored_bytes(uint8_t kind) { return pure_cell_text(kind) || kind == PURE_CELL_LIST; } -PURE_COLD void pure_layout_of(const PureModule *m, uint32_t record, PureLayout *out) { +void pure_layout_begin(PureLayout *l) { + l->records = 0, l->room = 4; + l->record = l->few, l->module_record = l->few_records; +} + +bool pure_layout_room(PureLayout *l, unsigned records) { + if (records <= l->room) return true; + if (records > PURE_LAYOUT_RECORDS) return false; + PureLayoutRecord *record = malloc(PURE_LAYOUT_RECORDS * sizeof(*record)); + uint16_t *module_record = malloc(PURE_LAYOUT_RECORDS * sizeof(*module_record)); + if (!record || !module_record) { + free(record), free(module_record); + return false; + } + memcpy(record, l->record, l->records * sizeof(*record)); + memcpy(module_record, l->module_record, l->records * sizeof(*module_record)); + pure_layout_done(l); + l->record = record, l->module_record = module_record, l->room = PURE_LAYOUT_RECORDS; + return true; +} + +void pure_layout_done(PureLayout *l) { + if (l->record != l->few) free(l->record), free(l->module_record); + l->record = l->few, l->module_record = l->few_records, l->room = 4; +} + +PURE_COLD bool pure_layout_of(const PureModule *m, uint32_t record, PureLayout *out) { out->records = 1; out->module_record[0] = (uint16_t)record; for (unsigned at = 0; at < out->records; ++at) { /* breadth first: each record once, numbered as first met */ @@ -6013,10 +6038,12 @@ PURE_COLD void pure_layout_of(const PureModule *m, uint32_t record, PureLayout * uint32_t items = nested_record(m, field); unsigned k = 0; while (k < out->records && out->module_record[k] != items) ++k; + if (k == out->records && !pure_layout_room(out, out->records + 1)) return false; if (k == out->records) out->module_record[out->records++] = (uint16_t)items; out->record[at].items[f] = (uint8_t)k; } } + return true; } PURE_COLD bool pure_layout_same(const PureLayout *a, const PureLayout *b) { @@ -6161,10 +6188,11 @@ PURE_COLD PureResult pure_list_migrate(PureList **out, const PureList *from, con PURE_COLD static PureResult keep_list(PureList **out, PureList *from, const PureModule *old, uint32_t old_record, const PureModule *m, uint32_t record, bool kept) { PureLayout was, now; - pure_layout_of(old, old_record, &was); - pure_layout_of(m, record, &now); - if (pure_layout_same(&was, &now)) { *out = from; return PURE_OK; } - return pure_list_migrate(out, from, &was, m, record, kept); + pure_layout_begin(&was), pure_layout_begin(&now); + PureResult result = !pure_layout_of(old, old_record, &was) || !pure_layout_of(m, record, &now) ? PURE_ALLOCATION : + pure_layout_same(&was, &now) ? (*out = from, PURE_OK) : pure_list_migrate(out, from, &was, m, record, kept); + pure_layout_done(&was), pure_layout_done(&now); + return result; } /* Open a module in an app. States keep their values by name and kind (texts |
