aboutsummaryrefslogtreecommitdiffstats
path: root/core/module.c
diff options
context:
space:
mode:
authoreunhhu <[email protected]>2026-10-19 00:16:56 +0100
committereunhhu <[email protected]>2026-10-19 00:16:56 +0100
commit3cc6bc3d8a1d8827519decbf7e084e89110c93f9 (patch)
treeeb2aa0a0df93815a562e270696b6de3717198c0f /core/module.c
parentd7caf4dfb1947d8f804e3d8ae7ef066c6e3b8fb7 (diff)
downloadpure-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.c40
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