From 0f0a44257874478eaacd60a6a9ad446bd7716ef5 Mon Sep 17 00:00:00 2001 From: Mattia Giambirtone Date: Wed, 25 May 2022 14:38:34 +0200 Subject: [PATCH] Fixed issues with stack frames when returning from functions --- src/backend/vm.nim | 2 +- src/config.nim | 2 +- src/frontend/compiler.nim | 4 +++- src/main.nim | 26 ++++++++++++++++---------- src/tests.pn | 8 ++++---- 5 files changed, 25 insertions(+), 17 deletions(-) diff --git a/src/backend/vm.nim b/src/backend/vm.nim index 9c043f3..85a73fc 100644 --- a/src/backend/vm.nim +++ b/src/backend/vm.nim @@ -239,7 +239,7 @@ proc dispatch*(self: PeonVM) = # pushing it on the stack let retVal = self.pop() let frame = self.frames.pop() - for i in countdown(0, frame): + for i in countdown(frame, 1): discard self.pop() self.ip = int(self.pop().uInt) self.push(retVal) diff --git a/src/config.nim b/src/config.nim index 1fda235..6014eb9 100644 --- a/src/config.nim +++ b/src/config.nim @@ -27,7 +27,7 @@ when len(PEON_COMMIT_HASH) != 40: const PEON_BRANCH* = "master" when len(PEON_BRANCH) > 255: {.fatal: "The git branch name's length must be less than or equal to 255 characters".} -const DEBUG_TRACE_VM* = false # Traces VM execution +const DEBUG_TRACE_VM* = true # Traces VM execution const DEBUG_TRACE_GC* = false # Traces the garbage collector (TODO) const DEBUG_TRACE_ALLOCATION* = false # Traces memory allocation/deallocation const DEBUG_TRACE_COMPILER* = false # Traces the compiler diff --git a/src/frontend/compiler.nim b/src/frontend/compiler.nim index a08a1e3..4f99823 100644 --- a/src/frontend/compiler.nim +++ b/src/frontend/compiler.nim @@ -940,12 +940,14 @@ proc identifier(self: Compiler, node: IdentExpr) = else: self.detectClosureVariable(s.name) let t = self.getStackPos(node) - let index = t.pos + var index = t.pos # We don't check if index is -1 because if it # were, self.resolve() would have returned nil if not t.closedOver: # Static name resolution, loads value at index in the stack. Very fast. Much wow. self.emitByte(LoadVar) + if self.scopeDepth > 0: + inc(index) # Skip the return address! self.emitBytes((index - self.frames[self.scopeDepth]).toTriple()) else: if self.closedOver.len() == 0: diff --git a/src/main.nim b/src/main.nim index 916c074..86ac54a 100644 --- a/src/main.nim +++ b/src/main.nim @@ -3,6 +3,8 @@ import strformat import strutils import terminal import parseopt +import nimSHA2 +import times import os # Thanks art <3 @@ -20,6 +22,7 @@ import frontend/parser as p import frontend/compiler as c import backend/vm as v import util/serializer as s +import util/debugger import config # Forward declarations @@ -29,17 +32,10 @@ proc getLineEditor: LineEditor # Handy dandy compile-time constants const debugLexer = false const debugParser = false -const debugCompiler = true -const debugSerializer = true +const debugCompiler = false +const debugSerializer = false const debugRuntime = false - -when debugSerializer: - import nimSHA2 - import times - -when debugCompiler: - import util/debugger - + proc repl = styledEcho fgMagenta, "Welcome into the peon REPL!" @@ -123,6 +119,11 @@ proc repl = styledEcho fgGreen, "OK" else: styledEcho fgRed, "Corrupted" + stdout.styledWrite(fgBlue, "\t- CFI segment: ") + if serialized.chunk.cfi == compiled.cfi: + styledEcho fgGreen, "OK" + else: + styledEcho fgRed, "Corrupted" when debugRuntime: styledEcho fgCyan, "\n\nExecution step: " vm.run(serialized.chunk) @@ -240,6 +241,11 @@ proc runFile(f: string) = styledEcho fgGreen, "OK" else: styledEcho fgRed, "Corrupted" + stdout.styledWrite(fgBlue, "\t- CFI segment: ") + if serialized.chunk.cfi == compiled.cfi: + styledEcho fgGreen, "OK" + else: + styledEcho fgRed, "Corrupted" when debugRuntime: styledEcho fgCyan, "\n\nExecution step: " vm.run(serialized.chunk) diff --git a/src/tests.pn b/src/tests.pn index a422187..0631a8f 100644 --- a/src/tests.pn +++ b/src/tests.pn @@ -6,11 +6,11 @@ operator `+`(a: int32): int32 { return a; } -fn `+`(a, b: int): int { - return a + b; +fn `+`(a, b: int): int32 { + return 0'i32; # Just to test error messages } -var `+`: int = 1; # hehehehe +var `+`: int = 1; # Can't call a value! +1; # Works: defined for int64 -# +1'u8; # Nope! ++1'u8; # No implementation for uint8, error!