#include #include "forth.h" #include "fh_runtime.h" #include "fh_mem.h" /** Allocate a heap region, e.g. for a string. The address is stored to `addr` */ enum fh_error fh_heap_reserve( struct fh_thread_s *fh, size_t len, uint32_t *addr ) { uint32_t p = WORDALIGNED(fh->heap_top); // FIXME this shouldn't be needed if (p + len > HEAP_SIZE) { return FH_ERR_HEAP_FULL; } *addr = p; fh->heap_top = WORDALIGNED(p + len); return FH_OK; } /** Write bytes to heap at a given location. The region must have been previously allocated! */ void fh_heap_write(struct fh_thread_s *fh, uint32_t addr, const void *src, uint32_t len) { memcpy(&fh->heap[addr], src, len); } /** Allocate heap region and write bytes to it */ enum fh_error fh_heap_put(struct fh_thread_s *fh, const void *src, uint32_t len) { enum fh_error rv; uint32_t addr; TRY(fh_heap_reserve(fh, len, &addr)); fh_heap_write(fh, addr, src, len); return FH_OK; } /** Copy bytes from compile area to heap. The region must have been previously allocated! */ void fh_heap_copy_from_compile(struct fh_thread_s *fh, uint32_t addr, uint32_t srcaddr, uint32_t len) { memcpy(&fh->heap[addr], &fh->compile[srcaddr], len); } /** Reserve space in the compile memory area */ enum fh_error fh_compile_reserve( struct fh_thread_s *fh, size_t len, uint32_t *addr ) { uint32_t p = WORDALIGNED(fh->compile_top); // FIXME this shouldn't be needed if (p + len > COMPILED_BUFFER_SIZE) { return FH_ERR_HEAP_FULL; } *addr = p; fh->compile_top = WORDALIGNED(p + len); return FH_OK; } /** Write bytes to compile area at a given location. The region must have been previously allocated! */ void fh_compile_write(struct fh_thread_s *fh, uint32_t addr, const void *src, uint32_t len) { memcpy(&fh->compile[addr], src, len); } /** Allocate compile region and write bytes to it */ enum fh_error fh_compile_put(struct fh_thread_s *fh, const void *src, uint32_t len) { enum fh_error rv; uint32_t addr; TRY(fh_compile_reserve(fh, len, &addr)); fh_compile_write(fh, addr, src, len); return FH_OK; }