/* image.c -- the StarForth nucleus, as its host knows it. See image.h. * * Nothing here uses the C library: the bare-metal kernel links this file. */ #include "v4/image.h" int v4_image_born(v4_node *n, v4_exec_state *es, v4_heat *h, const v4_image *im) { if (im->cell_bits != (unsigned)V4_CELL_BITS || im->node_words != (unsigned)V4_NODE_WORDS || im->data_ring != (unsigned)V4_DATA_RING || im->ret_ring != (unsigned)V4_RET_RING) return 0; v4_node_born(n, im->port); v4_exec_reset(es); v4_heat_reset(h); v4_node_console_attach(n, im->console_tx); v4_node_console_input_attach(n, im->console_rx, im->console_status); v4_node_stack_regs_attach(n, im->dstack_reg, im->rstack_reg); v4_node_error_attach(n, im->node_error); v4_node_fault_attach(n, im->fault_table); return 1; } int v4_image_waiting(const v4_node *n, const v4_image *im) { return n->input_pos == n->input_len && n->p >= im->key_start && n->p < im->key_end; } void v4_image_seal(v4_node *n, const v4_image *im) { n->mem[im->boot_cells] = n->mem[im->dp]; n->mem[im->boot_cells + 1] = n->mem[im->latest]; n->mem[im->fence] = (n->mem[im->dp] + 3) / 4; } /* FNV-1a over the node's memory below HERE, a cell at a time, low byte * first, and then LATEST. */ #define FNV_OFFSET 0xcbf29ce484222325ULL #define FNV_PRIME 0x00000100000001b3ULL static uint64_t hash_cell(uint64_t h, v4_cell c) { v4_ucell u = (v4_ucell)c; unsigned i; for (i = 0; i < V4_CELL_BITS / 8; i++) { h ^= (uint64_t)((u >> (8 * i)) & 0xffu); h *= FNV_PRIME; } return h; } uint64_t v4_image_dict_hash(const v4_node *n, const v4_image *im) { uint64_t h = FNV_OFFSET; v4_cell here = (n->mem[im->dp] + 3) / 4, k; if (here < 0) here = 0; if (here > (v4_cell)V4_NODE_WORDS) here = (v4_cell)V4_NODE_WORDS; for (k = 0; k < here; k++) h = hash_cell(h, n->mem[k]); return hash_cell(h, n->mem[im->latest]); }