Fixed a bug where regular functions were mistaken for closures
This commit is contained in:
parent
ca5a1c1bc9
commit
3e6e9da475
|
@ -31,7 +31,7 @@ when debugVM or debugMem or debugGC:
|
||||||
import std/terminal
|
import std/terminal
|
||||||
|
|
||||||
|
|
||||||
{.push checks:not disableVMChecks.} # The VM is a critical point where checks are deleterious
|
{.push checks:enableVMChecks.} # The VM is a critical point where checks are deleterious
|
||||||
|
|
||||||
type
|
type
|
||||||
PeonVM* = ref object
|
PeonVM* = ref object
|
||||||
|
@ -339,10 +339,10 @@ proc newPeonVM*: PeonVM =
|
||||||
result.initCache()
|
result.initCache()
|
||||||
result.gc = newPeonGC()
|
result.gc = newPeonGC()
|
||||||
result.frames = @[]
|
result.frames = @[]
|
||||||
result.calls = @[]
|
|
||||||
result.operands = @[]
|
result.operands = @[]
|
||||||
result.results = @[]
|
result.results = @[]
|
||||||
result.envs = @[]
|
result.envs = @[]
|
||||||
|
result.calls = @[]
|
||||||
result.gc.vm = result
|
result.gc.vm = result
|
||||||
|
|
||||||
|
|
||||||
|
@ -625,7 +625,7 @@ when debugVM: # So nim shuts up
|
||||||
stdout.styledWrite(fgGreen, "Call Stack: ", fgMagenta, "[")
|
stdout.styledWrite(fgGreen, "Call Stack: ", fgMagenta, "[")
|
||||||
for i, e in self.calls:
|
for i, e in self.calls:
|
||||||
stdout.styledWrite(fgYellow, $e)
|
stdout.styledWrite(fgYellow, $e)
|
||||||
if i < self.calls.high():
|
if i < self.calls.len():
|
||||||
stdout.styledWrite(fgYellow, ", ")
|
stdout.styledWrite(fgYellow, ", ")
|
||||||
styledEcho fgMagenta, "]"
|
styledEcho fgMagenta, "]"
|
||||||
if self.operands.len() !> 0:
|
if self.operands.len() !> 0:
|
||||||
|
@ -709,8 +709,6 @@ proc dispatch*(self: PeonVM) =
|
||||||
of LoadUInt8:
|
of LoadUInt8:
|
||||||
self.push(uint64(self.constReadUInt8(int(self.readLong()))))
|
self.push(uint64(self.constReadUInt8(int(self.readLong()))))
|
||||||
of LoadString:
|
of LoadString:
|
||||||
# TODO: Use constReadString with own memory manager
|
|
||||||
# Strings are broken rn!!
|
|
||||||
self.push(cast[uint64](self.constReadString(int(self.readLong()), int(self.readLong()))))
|
self.push(cast[uint64](self.constReadString(int(self.readLong()), int(self.readLong()))))
|
||||||
# We cast instead of converting because, unlike with integers,
|
# We cast instead of converting because, unlike with integers,
|
||||||
# we don't want nim to touch any of the bits of the underlying
|
# we don't want nim to touch any of the bits of the underlying
|
||||||
|
|
|
@ -27,7 +27,7 @@ const debugStressGC* {.booldefine.} = false # Make the GC run a collection at
|
||||||
const PeonBytecodeMarker* = "PEON_BYTECODE" # Magic value at the beginning of bytecode files
|
const PeonBytecodeMarker* = "PEON_BYTECODE" # Magic value at the beginning of bytecode files
|
||||||
const HeapGrowFactor* = 2 # The growth factor used by the GC to schedule the next collection
|
const HeapGrowFactor* = 2 # The growth factor used by the GC to schedule the next collection
|
||||||
const FirstGC* = 1024 * 1024; # How many bytes to allocate before running the first GC
|
const FirstGC* = 1024 * 1024; # How many bytes to allocate before running the first GC
|
||||||
const disableVMChecks* {.booldefine.} = true; # Disables all types of compiler (nim-wise) checks in the VM
|
const enableVMChecks* {.booldefine.} = true; # Enables all types of compiler (nim-wise) checks in the VM
|
||||||
when HeapGrowFactor <= 1:
|
when HeapGrowFactor <= 1:
|
||||||
{.fatal: "Heap growth factor must be > 1".}
|
{.fatal: "Heap growth factor must be > 1".}
|
||||||
const PeonVersion* = (major: 0, minor: 1, patch: 0)
|
const PeonVersion* = (major: 0, minor: 1, patch: 0)
|
||||||
|
@ -35,7 +35,7 @@ const PeonRelease* = "alpha"
|
||||||
const PeonCommitHash* = "9884975fbd0bd2880f0969d21ee7b6ae44ecbafa"
|
const PeonCommitHash* = "9884975fbd0bd2880f0969d21ee7b6ae44ecbafa"
|
||||||
when len(PeonCommitHash) != 40:
|
when len(PeonCommitHash) != 40:
|
||||||
{.fatal: "The git commit hash must be exactly 40 characters long".}
|
{.fatal: "The git commit hash must be exactly 40 characters long".}
|
||||||
const PeonBranch* = "master"
|
const PeonBranch* = "fixed-size-stack"
|
||||||
when len(PeonBranch) > 255 or len(PeonBranch) == 0:
|
when len(PeonBranch) > 255 or len(PeonBranch) == 0:
|
||||||
{.fatal: "The git branch name's length must be within 1 and 255 characters".}
|
{.fatal: "The git branch name's length must be within 1 and 255 characters".}
|
||||||
const PeonVersionString* = &"Peon {PeonVersion.major}.{PeonVersion.minor}.{PeonVersion.patch} {PeonRelease} ({PeonBranch}, {CompileDate}, {CompileTime}, {PeonCommitHash[0..8]}) [Nim {NimVersion}] on {hostOS} ({hostCPU})"
|
const PeonVersionString* = &"Peon {PeonVersion.major}.{PeonVersion.minor}.{PeonVersion.patch} {PeonRelease} ({PeonBranch}, {CompileDate}, {CompileTime}, {PeonCommitHash[0..8]}) [Nim {NimVersion}] on {hostOS} ({hostCPU})"
|
||||||
|
|
|
@ -146,6 +146,8 @@ type
|
||||||
# The current scope depth. If > 0, we're
|
# The current scope depth. If > 0, we're
|
||||||
# in a local scope, otherwise it's global
|
# in a local scope, otherwise it's global
|
||||||
scopeDepth: int
|
scopeDepth: int
|
||||||
|
# Scope ownership data
|
||||||
|
scopeOwners: seq[tuple[owner: Name, depth: int]]
|
||||||
# The current function being compiled
|
# The current function being compiled
|
||||||
currentFunction: Name
|
currentFunction: Name
|
||||||
# Are optimizations turned on?
|
# Are optimizations turned on?
|
||||||
|
@ -237,6 +239,8 @@ proc newCompiler*(enableOptimizations: bool = true, replMode: bool = false): Com
|
||||||
result.compilerProcs["magic"] = handleMagicPragma
|
result.compilerProcs["magic"] = handleMagicPragma
|
||||||
result.compilerProcs["pure"] = handlePurePragma
|
result.compilerProcs["pure"] = handlePurePragma
|
||||||
result.source = ""
|
result.source = ""
|
||||||
|
result.scopeOwners = @[]
|
||||||
|
|
||||||
|
|
||||||
## Public getters for nicer error formatting
|
## Public getters for nicer error formatting
|
||||||
proc getCurrentNode*(self: Compiler): ASTNode = (if self.current >=
|
proc getCurrentNode*(self: Compiler): ASTNode = (if self.current >=
|
||||||
|
@ -1031,6 +1035,7 @@ proc beginScope(self: Compiler) =
|
||||||
## Begins a new local scope by incrementing the current
|
## Begins a new local scope by incrementing the current
|
||||||
## scope's depth
|
## scope's depth
|
||||||
inc(self.scopeDepth)
|
inc(self.scopeDepth)
|
||||||
|
self.scopeOwners.add((self.currentFunction, self.scopeDepth))
|
||||||
|
|
||||||
|
|
||||||
proc `$`(self: Type): string = $self[]
|
proc `$`(self: Type): string = $self[]
|
||||||
|
@ -1053,6 +1058,7 @@ proc endScope(self: Compiler) =
|
||||||
if self.scopeDepth < 0:
|
if self.scopeDepth < 0:
|
||||||
self.error("cannot call endScope with scopeDepth < 0 (This is an internal error and most likely a bug)")
|
self.error("cannot call endScope with scopeDepth < 0 (This is an internal error and most likely a bug)")
|
||||||
dec(self.scopeDepth)
|
dec(self.scopeDepth)
|
||||||
|
discard self.scopeOwners.pop()
|
||||||
var names: seq[Name] = @[]
|
var names: seq[Name] = @[]
|
||||||
var popCount = 0
|
var popCount = 0
|
||||||
for name in self.names:
|
for name in self.names:
|
||||||
|
@ -1346,6 +1352,7 @@ proc beginProgram(self: Compiler, incremental: bool = false): int =
|
||||||
isFunDecl: true,
|
isFunDecl: true,
|
||||||
line: -1)
|
line: -1)
|
||||||
self.names.add(main)
|
self.names.add(main)
|
||||||
|
self.scopeOwners.add((main, 0))
|
||||||
self.emitByte(LoadInt64, 1)
|
self.emitByte(LoadInt64, 1)
|
||||||
self.emitBytes(self.chunk.writeConstant(main.codePos.toLong()), 1)
|
self.emitBytes(self.chunk.writeConstant(main.codePos.toLong()), 1)
|
||||||
self.emitByte(LoadUInt32, 1)
|
self.emitByte(LoadUInt32, 1)
|
||||||
|
@ -1485,7 +1492,7 @@ proc identifier(self: Compiler, node: IdentExpr) =
|
||||||
# a location to jump to
|
# a location to jump to
|
||||||
self.emitByte(LoadInt64, node.token.line)
|
self.emitByte(LoadInt64, node.token.line)
|
||||||
self.emitBytes(self.chunk.writeConstant(s.codePos.toLong()), node.token.line)
|
self.emitBytes(self.chunk.writeConstant(s.codePos.toLong()), node.token.line)
|
||||||
elif self.scopeDepth > 0 and not self.currentFunction.isNil() and s.depth != self.scopeDepth:
|
elif self.scopeDepth > 0 and not self.currentFunction.isNil() and s.depth != self.scopeDepth and self.scopeOwners[s.depth].owner != self.currentFunction:
|
||||||
# Loads a closure variable. Stored in a separate "closure array" in the VM that does not
|
# Loads a closure variable. Stored in a separate "closure array" in the VM that does not
|
||||||
# align its semantics with the call stack. This makes closures work as expected and is
|
# align its semantics with the call stack. This makes closures work as expected and is
|
||||||
# not much slower than indexing our stack (since they're both dynamic arrays at runtime anyway)
|
# not much slower than indexing our stack (since they're both dynamic arrays at runtime anyway)
|
||||||
|
|
Loading…
Reference in New Issue