# Copyright 2022 Mattia Giambirtone # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ## Memory allocator from JAPL import std/segfaults import ../config when debugMem: import std/strformat proc reallocate*(p: pointer, oldSize: int, newSize: int): pointer = ## Simple wrapper around realloc/dealloc try: if newSize == 0 and p != nil: when debugMem: if oldSize > 1: echo &"DEBUG - Memory manager: Deallocating {oldSize} bytes" else: echo "DEBUG - Memory manager: Deallocating 1 byte" dealloc(p) return nil when debugMem: if pointr == nil and newSize == 0: echo &"DEBUG - Memory manager: Warning, asked to dealloc() nil pointer from {oldSize} to {newSize} bytes, ignoring request" if oldSize > 0 and p != nil or oldSize == 0: when debugMem: if oldSize == 0: if newSize > 1: echo &"DEBUG - Memory manager: Allocating {newSize} bytes of memory" else: echo "DEBUG - Memory manager: Allocating 1 byte of memory" else: echo &"DEBUG - Memory manager: Resizing {oldSize} bytes of memory to {newSize} bytes" result = realloc(p, newSize) when debugMem: if oldSize > 0 and pointr == nil: echo &"DEBUG - Memory manager: Warning, asked to realloc() nil pointer from {oldSize} to {newSize} bytes, ignoring request" except NilAccessDefect: stderr.write("Peon: could not manage memory, segmentation fault\n") quit(139) # For now, there's not much we can do if we can't get the memory we need, so we exit template resizeArray*(kind: untyped, p: pointer, oldCount, newCount: int): untyped = ## Handy template to resize a dynamic array cast[ptr UncheckedArray[kind]](reallocate(p, sizeof(kind) * oldCount, sizeof(kind) * newCount)) template freeArray*(kind: untyped, p: pointer, oldCount: int): untyped = ## Frees a dynamic array reallocate(p, sizeof(kind) * oldCount, 0) template free*(kind: untyped, p: pointer): untyped = ## Frees a pointer by reallocating its ## size to 0 reallocate(p, sizeof(kind), 0) template growCapacity*(capacity: int): untyped = ## Handy template used to calculate how much ## more memory is needed when reallocating ## dynamic arrays if capacity < 8: 8 else: capacity * HeapGrowFactor template allocate*(castTo: untyped, sizeTo: untyped, count: int): untyped = ## Allocates an object and casts its pointer to the specified type cast[ptr castTo](reallocate(nil, 0, sizeof(sizeTo) * count))