// 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 allocate(size: I32, align: I32): I32 = ( if align < 4_I32 then std.abort("invalid alignment"); // 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 newHeadPtr = alignedPtr + size; 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; alignedPtr ); function deallocate(ptr: I32, size: I32) = ( std.println("uwu deawwocate :3"); ); // Port of https://github.com/CCareaga/heap_allocator fc423c6113df598ac8d10bc1f2954d51248e6443 // // 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: HeapPtr = 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; type NodeS = struct { hole: I32, size: I32, next: *NodeS, prev: *NodeS, }; type FootS = struct { header: *NodeS, }; type BinS = struct { head: *NodeS, }; global SIZEOF_NODE: I32 = 16_I32; global SIZEOF_FOOTER: I32 = 4_I32; type HeapPtr = I32; type NodePtr = I32; type FootPtr = I32; type BinPtr = I32; function initHeap() = ( let heap_init_size = 65536_I32 - HEAP_REGION_START; let init_region: *NodeS = ___transmute(HEAP_REGION_START); init_region.hole = 1_I32; init_region.size = heap_init_size - SIZEOF_NODE - SIZEOF_FOOTER; createFoot(init_region); ); function createFoot(head: *NodeS) = ( let foot = getFoot(head); foot.header = head; ); function getFoot(node: *NodeS): *FootS = ( let node_addr: I32 = ___transmute(node); ___transmute(node_addr + SIZEOF_NODE + node.size) ); function getWilderness() =; // llist.c function addNode(bin: *BinS, node: *NodeS) = ( node.next = __NULL; node.prev = __NULL; if (bin.head == __NULL) then ( bin.head = node; ) else ( let current: *NodeS = bin.head; let previous: *NodeS = ___transmute(0_I32); loop ( let currentAddr: I32 = ___transmute(current); if (currentAddr != 0_I32) & (current.size <= node.size) then break; previous = current; current = current.next; ); let currentAddr: I32 = ___transmute(current); if (currentAddr == 0_I32) then ( previous.next = node; node.prev = previous; ) else ( let previous_addr: I32 = ___transmute(previous); if (previous_addr != 0_I32) then ( node.next = current; previous.next = node; node.prev = previous; current.prev = node; ) else ( node.next = bin.head; bin.head.prev = node; bin.head = node; ); ); ) ); function removeNode(bin: *BinS, node: *NodeS) = ( if (bin.head != __NULL) then ( if (bin.head == node) then ( bin.head = bin.head.next; ) else ( let temp: *NodeS = bin.head.next; loop ( if (temp == __NULL) then break; if (temp == node) then ( ) ) ) ) ); function test() =;