Removed makefile + minor fixes

This commit is contained in:
Mattia Giambirtone 2022-10-11 09:07:25 +02:00
parent 3e6e9da475
commit 15f3143599
2 changed files with 41 additions and 30 deletions

View File

@ -1,5 +0,0 @@
repl:
nim --hints:off --warnings:off r src/main.nim
pretty:
nimpretty src/*.nim src/backend/*.nim src/frontend/*.nim src/frontend/meta/*.nim src/memory/*.nim src/util/*.nim

View File

@ -57,7 +57,7 @@ type
closures: seq[uint64] # Stores closure offsets
envs: seq[uint64] # Stores variables that do not have stack semantics
results: seq[uint64] # Stores function's results (return values)
gc: PeonGC
gc: PeonGC # Our memory manager
ObjectKind* = enum
## A tag for heap-allocated
## peon objects
@ -77,7 +77,10 @@ type
discard # TODO
PeonGC* = ref object
## A simple Mark&Sweep collector
## to manage peon's heap space
## to manage peon's heap space.
## All heap allocation goes through
## this system and is not handled
## manually by the VM
vm: PeonVM
bytesAllocated: tuple[total, current: int]
nextGC: int
@ -155,7 +158,7 @@ template free*(self: PeonGC, kind: typedesc, p: pointer): untyped =
proc allocate*(self: PeonGC, kind: ObjectKind, size: typedesc, count: int): ptr HeapObject {.inline.} =
## Allocates aobject on the heap
result = cast[ptr HeapObject](self.reallocate(nil, 0, sizeof(HeapObject) * 1))
result = cast[ptr HeapObject](self.reallocate(nil, 0, sizeof(HeapObject)))
result.marked = false
self.bytesAllocated.total += sizeof(result)
self.bytesAllocated.current += sizeof(result)
@ -182,7 +185,8 @@ proc markRoots(self: PeonGC): seq[ptr HeapObject] =
## Marks root objects *not* to be
## collected by the GC and returns
## their addresses
when debugGC:
echo "DEBUG - GC: Starting mark phase"
# Unlike what bob does in his book,
# we keep track of objects in a different
# way due to how the whole thing is designed.
@ -204,9 +208,7 @@ proc markRoots(self: PeonGC): seq[ptr HeapObject] =
# we allocated and that would cause a memory leak, but
# with a 64-bit address-space it probably hardly matters,
# so I guess this is a mostly-precise Mark&Sweep collector
when debugGC:
echo "DEBUG - GC: Starting mark phase"
var live = initHashSet[uint64]()
var live = initHashSet[uint64](self.pointers.len())
for obj in self.vm.calls:
if obj in self.pointers:
live.incl(obj)
@ -223,7 +225,7 @@ proc markRoots(self: PeonGC): seq[ptr HeapObject] =
obj = cast[ptr HeapObject](p)
if obj.mark():
when debugGC:
echo &"DEBUG - GC: Marking object: {obj[]}"
echo &"DEBUG - GC: Marked object: {obj[]}"
result.add(obj)
when debugGC:
echo "DEBUG - GC: Mark phase complete"
@ -277,21 +279,21 @@ proc sweep(self: PeonGC) =
## nim disallows changing the
## size of a sequence during
## iteration
when debugGC:
echo "DEBUG - GC: Beginning sweeping phase"
var j = -1
var idx = 0
var count = 0
when debugGC:
var count = 0
while j < self.objects.high():
inc(j)
if self.objects[j].marked:
# Object is marked: don't touch it,
# but reset its mark so that it doesn't
# stay alive forever
self.objects[j].marked = false
when debugGC:
echo &"DEBUG - GC: Unmarking object: {self.objects[j][]}"
self.objects[j].marked = false
inc(idx)
else:
# Object is unmarked: its memory is
@ -299,7 +301,8 @@ proc sweep(self: PeonGC) =
self.free(self.objects[idx])
self.objects.delete(idx)
inc(idx)
inc(count)
when debugGC:
inc(count)
when debugGC:
echo &"DEBUG - GC: Swept {count} objects"
@ -308,9 +311,9 @@ proc collect(self: PeonGC) =
## Attempts to reclaim some
## memory from unreachable
## objects onto the heap
let before {.used.} = self.bytesAllocated.current
let time {.used.} = getMonoTime().ticks().float() / 1_000_000
when debugGC:
let before = self.bytesAllocated.current
let time = getMonoTime().ticks().float() / 1_000_000
echo &"DEBUG - GC: Starting collection cycle at heap size {self.bytesAllocated.current}"
self.trace(self.markRoots())
self.sweep()
@ -793,14 +796,14 @@ proc dispatch*(self: PeonVM) =
if self.frames.len() == 0:
# End of the program!
return
self.ip = ret.uInt
self.ip = ret.uint
of SetResult:
# Sets the result of the
# current function. A Return
# instruction will pop this
# off the results array and
# onto the operand stack when
# the current function exits.
# the current function exits
self.results[self.frames.high()] = self.pop()
of StoreVar:
# Stores the value at the top of the operand stack
@ -813,10 +816,12 @@ proc dispatch*(self: PeonVM) =
else:
self.pushc(self.pop())
of LoadClosure:
# Loads a closed-over variable onto the
# stack
# Loads a closed-over variable from the current
# environment onto the operand stack
self.push(self.getClosure(self.readLong().int))
of PopClosure:
# Discards a closed-over variable from the
# current environment
discard self.popClosure(self.readLong().int)
of StoreClosure:
# Stores/updates the value of a closed-over
@ -824,8 +829,8 @@ proc dispatch*(self: PeonVM) =
let item = self.getc(self.readLong().int)
self.setClosure(self.readLong().int, item)
of LoadVar:
# Pushes a variable onto the operand
# stack
# Pushes a variable from the call stack
# onto the operand stack
self.push(self.getc(self.readLong().int))
of NoOp:
# Does nothing
@ -863,32 +868,43 @@ proc dispatch*(self: PeonVM) =
# Relative, backward-jump
self.ip -= self.readLong()
of JumpIfFalse:
# Conditional positive jump
# Conditional, forward-jump
if not self.peek().bool:
self.ip += self.readLong()
of JumpIfTrue:
# Conditional positive jump
# Conditional (if the top of the stack
# equals true), forward-jump
let ip = self.readLong()
if self.peek().bool:
self.ip += ip
of JumpIfFalsePop:
# Conditional (if the top of the stack
# equals false), forward-jump. Always
# pops off the operand stack
let ip = self.readLong()
if not self.pop().bool:
self.ip += ip
of JumpIfFalseOrPop:
# Conditional (if the top of the stack
# equals false), forward-jump. Pops off
# the operand stack if the value at the
# top of the operand stack is true
let ip = self.readLong()
if not self.peek().bool:
self.ip += ip
else:
discard self.pop()
# Built-in operations on primitive types.
# Note: for operations where the order of
# the operands matters, we don't need to
# Note that, for operations where the order
# of the operands matters, we don't need to
# swap the order of the calls to pop: this
# is because operators are handled like peon
# functions, which means the arguments are
# already reversed on the stack when we
# execute the instruction
# execute the instruction. The beauty of the
# 2's complement system is that for most integer
# types, we don't need specialized instructions
# to operate on them
of Negate:
self.push(uint64(-int64(self.pop())))
of NegateFloat64: