58 lines
1.5 KiB
Nim
58 lines
1.5 KiB
Nim
import strformat
|
|
import strutils
|
|
|
|
type
|
|
UpvalueObj[T] = object
|
|
location*: ptr T
|
|
next*: Upvalue[T]
|
|
closed*: T
|
|
|
|
Upvalue*[T] = ptr UpvalueObj[T]
|
|
|
|
ClosureObj[T] = object
|
|
start: ptr uint8
|
|
upvalueCount*: int
|
|
upvalues: UncheckedArray[Upvalue[T]]
|
|
|
|
Closure*[T] = ptr ClosureObj[T]
|
|
|
|
proc newClosure*[T](start: ptr uint8, upvalueCount: int): Closure[T] =
|
|
result = cast[Closure[T]](alloc0(8 * upvalueCount + sizeof(ClosureObj[T])))
|
|
result.start = start
|
|
result.upvalueCount = upvalueCount
|
|
for i in 0 .. upvalueCount:
|
|
result.upvalues[i] = nil
|
|
|
|
proc getIp*[T](clos: Closure[T]): ptr uint8 =
|
|
clos.start
|
|
|
|
proc set*[T](clos: Closure[T], index: int, val: Upvalue[T]) =
|
|
clos.upvalues[index] = val
|
|
|
|
proc get*[T](clos: Closure[T], index: int): Upvalue[T] =
|
|
clos.upvalues[index]
|
|
|
|
proc debugStr*[T](clos: Closure[T]): string =
|
|
let addrUint: uint = cast[uint](clos.start)
|
|
let addrStr: string = addrUint.toHex()
|
|
let upvalCountStr: string = $clos.upvalueCount
|
|
result = &"Closure(start: {addrStr}, length: {upvalCountStr}, upvalues: "
|
|
mixin `$`
|
|
for i in 0 .. clos.upvalueCount-1:
|
|
if clos.upvalues[i] != nil:
|
|
let upvalStr = $(clos.upvalues[i].location[])
|
|
result &= &"{upvalStr}, "
|
|
else:
|
|
result &= "<unset>, "
|
|
result &= ")"
|
|
|
|
proc newUpvalue*[T](location: ptr T): Upvalue[T] =
|
|
result = cast[Upvalue[T]](alloc0(sizeof(UpvalueObj[T])))
|
|
result.location = location
|
|
result.next = nil
|
|
|
|
proc read*[T](upval: Upvalue[T]): T =
|
|
upval.location[]
|
|
|
|
proc write*[T](upval: Upvalue[T], val: T) =
|
|
upval.location[]= val |