wip closures: dedupliacation of upvalue references
This commit is contained in:
parent
086c6e3c2e
commit
f453de631d
|
@ -407,22 +407,30 @@ proc addUpvalue(comp: Compiler, index: int): int =
|
|||
## and creates an upvalue in every function up until the one
|
||||
## including this local so that all of the function scopes in between
|
||||
## have the right upvalue in them (compile time)
|
||||
|
||||
##
|
||||
## does not create duplicates: at each layer it will first find existing ones
|
||||
## and create references to that further down the line
|
||||
|
||||
template lenCheck(scope: Scope, blk: untyped) =
|
||||
if scope.upvalues.len() >= argMax:
|
||||
comp.error("Too many closure variables in function.")
|
||||
blk
|
||||
|
||||
let local = comp.locals[index]
|
||||
var scopeIndex = local.depth
|
||||
var scopeIndex = comp.locals[index].depth
|
||||
var isLocal = true
|
||||
var upvalIndex: int
|
||||
var upvalIndex: int = index
|
||||
while scopeIndex < comp.scopes.len():
|
||||
let scope = comp.scopes[scopeIndex]
|
||||
if scope.function:
|
||||
scope.lenCheck():
|
||||
return 0
|
||||
scope.upvalues.add(Upvalue(index: if isLocal: index else: upvalIndex, isLocal: isLocal))
|
||||
block ensure: # exiting this block means that the upvalueIndex is updated and points to the upvalue within scope
|
||||
for i in countup(0, scope.upvalues.high()):
|
||||
let upval = scope.upvalues[i]
|
||||
if upval.index == upvalIndex and upval.isLocal == isLocal:
|
||||
upvalIndex = i
|
||||
break ensure
|
||||
scope.upvalues.add(Upvalue(index: upvalIndex, isLocal: isLocal))
|
||||
isLocal = false
|
||||
upvalIndex = scope.upvalues.high()
|
||||
scopeIndex.inc
|
||||
|
|
Loading…
Reference in New Issue