// Start the heap at 1024. In practice this could probably be as low as we want. // TODO: The compiler should set this global to whatever it has calculated the heap // start to be. But well, 1024 ought to be enough for now. lol. global HEAD_PTR: I32 = 1024_I32; // Every struct has a header of an I32 as a refcount. // Allocate a new item. We do not deallocate anything yet. // lol. function allocateItem(objSize: I32, align: I32): I32 = ( if align < 4_I32 then std.abort("invalid alignment"); // Include the refcount header. let actualSize = 4_I32 + objSize; // Let's see whether we can fit the refcount into the align bits. // I happen to know that everything will always be at least 4 bytes aligned. let alignedPtr = std.alignUp(HEAD_PTR, align); let actualObjPtr = if (alignedPtr - HEAD_PTR) > align then ( alignedPtr - 4_I32 ) else ( // Take up the next spot. alignedPtr + align - 4_I32 ); let newHeadPtr = actualObjPtr + actualSize; if newHeadPtr > __memory_size() then ( // 16 pages, very arbitrary. let result = __memory_grow(16_I32); // If allocation failed we get -1. We don't have negative numbers yet, lol. if result > 4294967295_I32 then ( std.abort("failed to grow memory"); ); ); HEAD_PTR = newHeadPtr; actualObjPtr ); function deallocateItem(ptr: I32, objSize: I32) = ( std.println("uwu deawwocate :3"); ); // Port of https://github.com/CCareaga/heap_allocator // // MIT License // // Copyright (c) 2017 Chris Careaga // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. global HEAP_START: I32 = 2048_I32; // heap size = start+end+bin_t*BIN_COUNT // 4+ 4+ 4* 9 = 8+36=42 (round to 64) global HEAP_REGION_START: I32 = 2112_I32; // typedef struct node_t { // uint hole; // uint size; // struct node_t* next; // struct node_t* prev; // } node_t; // typedef struct { // node_t *header; // } footer_t; // typedef struct { // node_t* head; // } bin_t; global SIZEOF_NODE: I32 = 16_I32; global SIZEOF_FOOTER: I32 = 4_I32; function initHeap() = ( let heap_init_size = 65536_I32 - HEAP_REGION_START; __i32_store(HEAP_REGION_START, 1_I32); // START.hole = __i32_store(HEAP_REGION_START + 4_I32, heap_init_size - SIZEOF_NODE - SIZEOF_FOOTER); // START.size = ); function createFoot(head_node: I32) = ( let foot = getFoot(head_node); __i32_store(foot, head_node); // foot.header = head_node ); function getFoot(node: I32): I32 = ( let node_size = __i32_load(node + 4_I32); // node.size node + SIZEOF_NODE + node_size ); function addNode(bin: I32, node: I32) = ; function test() =;