Slotted in JAPL's old memory manager and fixed strings. Preliminary work for GC

This commit is contained in:
Mattia Giambirtone 2022-08-17 22:35:21 +02:00
parent 096bfaf662
commit 36970e493b
3 changed files with 56 additions and 13 deletions

View File

@ -21,6 +21,7 @@ import std/math
import ../config
import ../frontend/meta/bytecode
import ../util/multibyte
import ../memory/allocator
import strutils
@ -306,6 +307,18 @@ proc constReadFloat64(self: PeonVM, idx: int): float =
self.chunk.consts[idx + 4], self.chunk.consts[idx + 5],
self.chunk.consts[idx + 6], self.chunk.consts[idx + 7]]
copyMem(result.addr, arr.addr, sizeof(arr))
proc constReadString(self: PeonVM, size, idx: int): ptr UncheckedArray[char] =
## Reads a constant from the
## chunk's constant table and
## returns it as a pointer to
## a heap-allocated string
let str = self.chunk.consts[idx..<idx + size].fromBytes()
result = allocate(UncheckedArray[char], char, len(str))
for i, c in str:
result[i] = c
{.pop.}
@ -398,10 +411,7 @@ proc dispatch*(self: PeonVM) =
of LoadString:
# TODO: Use constReadString with own memory manager
# Strings are broken rn!!
let size = int(self.readLong())
let idx = int(self.readLong())
var str = self.chunk.consts[idx..<idx + size].fromBytes()
self.push(cast[uint64](str.addr))
self.push(cast[uint64](self.constReadString(int(self.readLong()), int(self.readLong()))))
# We cast instead of converting because, unlike with integers,
# we don't want nim to touch any of the bits of the underlying
# value!
@ -671,7 +681,7 @@ proc dispatch*(self: PeonVM) =
of PrintNan:
echo "nan"
of PrintString:
echo cast[ptr string](self.pop())[] # TODO
echo $cast[ptr UncheckedArray[char]](self.pop()) # TODO
of SysClock64:
# Pushes the value of a monotonic clock
# onto the operand stack. This can be used

View File

@ -1,3 +1,19 @@
# Copyright 2022 Mattia Giambirtone & All Contributors
#
# 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.
## Peon's main executable
# Builtins & external libs
import std/strformat
import std/strutils
@ -67,6 +83,8 @@ proc repl =
continue
elif input == "#reset":
compiled = newChunk()
compiler = newCompiler()
parser = newParser()
incremental = false
continue
elif input == "#clear":

View File

@ -25,7 +25,7 @@ when debugMem:
proc reallocate*(p: pointer, oldSize: int, newSize: int): pointer =
## Simple wrapper around realloc/dealloc
try:
if newSize == 0 and p != nil:
if newSize == 0 and not p.isNil():
when debugMem:
if oldSize > 1:
echo &"DEBUG - Memory manager: Deallocating {oldSize} bytes"
@ -33,10 +33,7 @@ proc reallocate*(p: pointer, oldSize: int, newSize: int): pointer =
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:
if oldSize > 0 and not p.isNil() or oldSize == 0:
when debugMem:
if oldSize == 0:
if newSize > 1:
@ -46,22 +43,40 @@ proc reallocate*(p: pointer, oldSize: int, newSize: int): pointer =
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:
if p.isNil() and newSize == 0:
echo &"DEBUG - Memory manager: Warning, asked to dealloc() nil pointer from {oldSize} to {newSize} bytes, ignoring request"
elif oldSize > 0 and p.isNil():
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
type
ObjectKind* = enum
String, List,
Dict, Tuple,
CustomType
HeapObject* = object
## A tag for a heap-allocated
## peon object
case kind*: ObjectKind
of String:
str*: ptr UncheckedArray[char]
len*: uint64
else:
discard # TODO
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 =
template freeArray*(kind: untyped, p: pointer, size: int): untyped =
## Frees a dynamic array
reallocate(p, sizeof(kind) * oldCount, 0)
reallocate(p, sizeof(kind) * size, 0)
template free*(kind: untyped, p: pointer): untyped =