first steps of making 'opt' a first class type for Nim
This commit is contained in:
parent
e879da5791
commit
f7f3a25be8
20 changed files with 198 additions and 35 deletions
|
|
@ -89,6 +89,19 @@ proc genericAssignAux(dest, src: pointer, mt: PNimType, shallow: bool) =
|
|||
cast[pointer](s +% i*% mt.base.size), mt.base, shallow)
|
||||
of tyRef:
|
||||
unsureAsgnRef(cast[PPointer](dest), cast[PPointer](s)[])
|
||||
of tyOptAsRef:
|
||||
let s2 = cast[PPointer](src)[]
|
||||
let d = cast[PPointer](dest)
|
||||
if s2 == nil:
|
||||
unsureAsgnRef(d, s2)
|
||||
else:
|
||||
when declared(usrToCell):
|
||||
let realType = usrToCell(s2).typ
|
||||
else:
|
||||
let realType = if mt.base.kind == tyObject: cast[ptr PNimType](s2)[]
|
||||
else: mt.base
|
||||
var z = newObj(realType, realType.base.size)
|
||||
genericAssignAux(d, addr z, mt.base, shallow)
|
||||
else:
|
||||
copyMem(dest, src, mt.size) # copy raw bits
|
||||
|
||||
|
|
@ -115,6 +128,7 @@ when false:
|
|||
of tyPtr: k = "ptr"
|
||||
of tyRef: k = "ref"
|
||||
of tyVar: k = "var"
|
||||
of tyOptAsRef: k = "optref"
|
||||
of tySequence: k = "seq"
|
||||
of tyProc: k = "proc"
|
||||
of tyPointer: k = "range"
|
||||
|
|
@ -195,7 +209,7 @@ proc genericReset(dest: pointer, mt: PNimType) =
|
|||
var d = cast[ByteAddress](dest)
|
||||
sysAssert(mt != nil, "genericReset 2")
|
||||
case mt.kind
|
||||
of tyString, tyRef, tySequence:
|
||||
of tyString, tyRef, tyOptAsRef, tySequence:
|
||||
unsureAsgnRef(cast[PPointer](dest), nil)
|
||||
of tyTuple:
|
||||
genericResetAux(dest, mt.node)
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ proc storeAux(dest, src: pointer, mt: PNimType, t: PRawChannel,
|
|||
for i in 0..(mt.size div mt.base.size)-1:
|
||||
storeAux(cast[pointer](d +% i*% mt.base.size),
|
||||
cast[pointer](s +% i*% mt.base.size), mt.base, t, mode)
|
||||
of tyRef:
|
||||
of tyRef, tyOptAsRef:
|
||||
var s = cast[PPointer](src)[]
|
||||
var x = cast[PPointer](dest)
|
||||
if s == nil:
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ proc genericDeepCopyAux(dest, src: pointer, mt: PNimType; tab: var PtrTable) =
|
|||
for i in 0..(mt.size div mt.base.size)-1:
|
||||
genericDeepCopyAux(cast[pointer](d +% i*% mt.base.size),
|
||||
cast[pointer](s +% i*% mt.base.size), mt.base, tab)
|
||||
of tyRef:
|
||||
of tyRef, tyOptAsRef:
|
||||
let s2 = cast[PPointer](src)[]
|
||||
if s2 == nil:
|
||||
unsureAsgnRef(cast[PPointer](dest), s2)
|
||||
|
|
|
|||
|
|
@ -349,7 +349,7 @@ proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: WalkOp) {.benign.} =
|
|||
for i in 0..n.len-1:
|
||||
# inlined for speed
|
||||
if n.sons[i].kind == nkSlot:
|
||||
if n.sons[i].typ.kind in {tyRef, tyString, tySequence}:
|
||||
if n.sons[i].typ.kind in {tyRef, tyOptAsRef, tyString, tySequence}:
|
||||
doOperation(cast[PPointer](d +% n.sons[i].offset)[], op)
|
||||
else:
|
||||
forAllChildrenAux(cast[pointer](d +% n.sons[i].offset),
|
||||
|
|
@ -366,7 +366,7 @@ proc forAllChildrenAux(dest: pointer, mt: PNimType, op: WalkOp) =
|
|||
if dest == nil: return # nothing to do
|
||||
if ntfNoRefs notin mt.flags:
|
||||
case mt.kind
|
||||
of tyRef, tyString, tySequence: # leaf:
|
||||
of tyRef, tyOptAsRef, tyString, tySequence: # leaf:
|
||||
doOperation(cast[PPointer](d)[], op)
|
||||
of tyObject, tyTuple:
|
||||
forAllSlotsAux(dest, mt.node, op)
|
||||
|
|
@ -379,13 +379,13 @@ proc forAllChildren(cell: PCell, op: WalkOp) =
|
|||
gcAssert(cell != nil, "forAllChildren: 1")
|
||||
gcAssert(isAllocatedPtr(gch.region, cell), "forAllChildren: 2")
|
||||
gcAssert(cell.typ != nil, "forAllChildren: 3")
|
||||
gcAssert cell.typ.kind in {tyRef, tySequence, tyString}, "forAllChildren: 4"
|
||||
gcAssert cell.typ.kind in {tyRef, tyOptAsRef, tySequence, tyString}, "forAllChildren: 4"
|
||||
let marker = cell.typ.marker
|
||||
if marker != nil:
|
||||
marker(cellToUsr(cell), op.int)
|
||||
else:
|
||||
case cell.typ.kind
|
||||
of tyRef: # common case
|
||||
of tyRef, tyOptAsRef: # common case
|
||||
forAllChildrenAux(cellToUsr(cell), cell.typ.base, op)
|
||||
of tySequence:
|
||||
var d = cast[ByteAddress](cellToUsr(cell))
|
||||
|
|
@ -461,7 +461,7 @@ proc rawNewObj(typ: PNimType, size: int, gch: var GcHeap): pointer =
|
|||
incTypeSize typ, size
|
||||
sysAssert(allocInv(gch.region), "rawNewObj begin")
|
||||
acquire(gch)
|
||||
gcAssert(typ.kind in {tyRef, tyString, tySequence}, "newObj: 1")
|
||||
gcAssert(typ.kind in {tyRef, tyOptAsRef, tyString, tySequence}, "newObj: 1")
|
||||
collectCT(gch)
|
||||
var res = cast[PCell](rawAlloc(gch.region, size + sizeof(Cell)))
|
||||
#gcAssert typ.kind in {tyString, tySequence} or size >= typ.base.size, "size too small"
|
||||
|
|
@ -509,7 +509,7 @@ proc newObjRC1(typ: PNimType, size: int): pointer {.compilerRtl.} =
|
|||
incTypeSize typ, size
|
||||
sysAssert(allocInv(gch.region), "newObjRC1 begin")
|
||||
acquire(gch)
|
||||
gcAssert(typ.kind in {tyRef, tyString, tySequence}, "newObj: 1")
|
||||
gcAssert(typ.kind in {tyRef, tyOptAsRef, tyString, tySequence}, "newObj: 1")
|
||||
collectCT(gch)
|
||||
sysAssert(allocInv(gch.region), "newObjRC1 after collectCT")
|
||||
|
||||
|
|
|
|||
|
|
@ -358,7 +358,7 @@ proc forAllChildrenAux(dest: pointer, mt: PNimType, op: WalkOp) =
|
|||
if dest == nil: return # nothing to do
|
||||
if ntfNoRefs notin mt.flags:
|
||||
case mt.kind
|
||||
of tyRef, tyString, tySequence: # leaf:
|
||||
of tyRef, tyOptAsRef, tyString, tySequence: # leaf:
|
||||
doOperation(cast[PPointer](d)[], op)
|
||||
of tyObject, tyTuple:
|
||||
forAllSlotsAux(dest, mt.node, op)
|
||||
|
|
@ -371,13 +371,13 @@ proc forAllChildren(cell: PCell, op: WalkOp) =
|
|||
gcAssert(cell != nil, "forAllChildren: 1")
|
||||
gcAssert(isAllocatedPtr(gch.region, cell), "forAllChildren: 2")
|
||||
gcAssert(cell.typ != nil, "forAllChildren: 3")
|
||||
gcAssert cell.typ.kind in {tyRef, tySequence, tyString}, "forAllChildren: 4"
|
||||
gcAssert cell.typ.kind in {tyRef, tyOptAsRef, tySequence, tyString}, "forAllChildren: 4"
|
||||
let marker = cell.typ.marker
|
||||
if marker != nil:
|
||||
marker(cellToUsr(cell), op.int)
|
||||
else:
|
||||
case cell.typ.kind
|
||||
of tyRef: # common case
|
||||
of tyRef, tyOptAsRef: # common case
|
||||
forAllChildrenAux(cellToUsr(cell), cell.typ.base, op)
|
||||
of tySequence:
|
||||
var d = cast[ByteAddress](cellToUsr(cell))
|
||||
|
|
@ -442,7 +442,7 @@ proc gcInvariant*() =
|
|||
proc rawNewObj(typ: PNimType, size: int, gch: var GcHeap): pointer =
|
||||
# generates a new object and sets its reference counter to 0
|
||||
sysAssert(allocInv(gch.region), "rawNewObj begin")
|
||||
gcAssert(typ.kind in {tyRef, tyString, tySequence}, "newObj: 1")
|
||||
gcAssert(typ.kind in {tyRef, tyOptAsRef, tyString, tySequence}, "newObj: 1")
|
||||
collectCT(gch)
|
||||
var res = cast[PCell](rawAlloc(gch.region, size + sizeof(Cell)))
|
||||
gcAssert((cast[ByteAddress](res) and (MemAlign-1)) == 0, "newObj: 2")
|
||||
|
|
@ -487,7 +487,7 @@ proc newSeq(typ: PNimType, len: int): pointer {.compilerRtl.} =
|
|||
proc newObjRC1(typ: PNimType, size: int): pointer {.compilerRtl.} =
|
||||
# generates a new object and sets its reference counter to 1
|
||||
sysAssert(allocInv(gch.region), "newObjRC1 begin")
|
||||
gcAssert(typ.kind in {tyRef, tyString, tySequence}, "newObj: 1")
|
||||
gcAssert(typ.kind in {tyRef, tyOptAsRef, tyString, tySequence}, "newObj: 1")
|
||||
collectCT(gch)
|
||||
sysAssert(allocInv(gch.region), "newObjRC1 after collectCT")
|
||||
|
||||
|
|
|
|||
|
|
@ -252,7 +252,7 @@ proc forAllChildrenAux(dest: pointer, mt: PNimType, op: WalkOp) =
|
|||
if dest == nil: return # nothing to do
|
||||
if ntfNoRefs notin mt.flags:
|
||||
case mt.kind
|
||||
of tyRef, tyString, tySequence: # leaf:
|
||||
of tyRef, tyOptAsRef, tyString, tySequence: # leaf:
|
||||
doOperation(cast[PPointer](d)[], op)
|
||||
of tyObject, tyTuple:
|
||||
forAllSlotsAux(dest, mt.node, op)
|
||||
|
|
@ -264,13 +264,13 @@ proc forAllChildrenAux(dest: pointer, mt: PNimType, op: WalkOp) =
|
|||
proc forAllChildren(cell: PCell, op: WalkOp) =
|
||||
gcAssert(cell != nil, "forAllChildren: 1")
|
||||
gcAssert(cell.typ != nil, "forAllChildren: 2")
|
||||
gcAssert cell.typ.kind in {tyRef, tySequence, tyString}, "forAllChildren: 3"
|
||||
gcAssert cell.typ.kind in {tyRef, tyOptAsRef, tySequence, tyString}, "forAllChildren: 3"
|
||||
let marker = cell.typ.marker
|
||||
if marker != nil:
|
||||
marker(cellToUsr(cell), op.int)
|
||||
else:
|
||||
case cell.typ.kind
|
||||
of tyRef: # common case
|
||||
of tyRef, tyOptAsRef: # common case
|
||||
forAllChildrenAux(cellToUsr(cell), cell.typ.base, op)
|
||||
of tySequence:
|
||||
var d = cast[ByteAddress](cellToUsr(cell))
|
||||
|
|
@ -285,7 +285,7 @@ proc rawNewObj(typ: PNimType, size: int, gch: var GcHeap): pointer =
|
|||
# generates a new object and sets its reference counter to 0
|
||||
incTypeSize typ, size
|
||||
acquire(gch)
|
||||
gcAssert(typ.kind in {tyRef, tyString, tySequence}, "newObj: 1")
|
||||
gcAssert(typ.kind in {tyRef, tyOptAsRef, tyString, tySequence}, "newObj: 1")
|
||||
collectCT(gch)
|
||||
var res = cast[PCell](rawAlloc(gch.region, size + sizeof(Cell)))
|
||||
gcAssert((cast[ByteAddress](res) and (MemAlign-1)) == 0, "newObj: 2")
|
||||
|
|
|
|||
|
|
@ -62,6 +62,21 @@ type
|
|||
tyUInt16,
|
||||
tyUInt32,
|
||||
tyUInt64,
|
||||
tyOptAsRef, tyUnused1, tyUnused2,
|
||||
tyVarargsHidden,
|
||||
tyUnusedHidden,
|
||||
tyProxyHidden,
|
||||
tyBuiltInTypeClassHidden,
|
||||
tyUserTypeClassHidden,
|
||||
tyUserTypeClassInstHidden,
|
||||
tyCompositeTypeClassHidden,
|
||||
tyInferredHidden,
|
||||
tyAndHidden, tyOrHidden, tyNotHidden,
|
||||
tyAnythingHidden,
|
||||
tyStaticHidden,
|
||||
tyFromExprHidden,
|
||||
tyOpt,
|
||||
tyVoidHidden
|
||||
|
||||
TNimNodeKind = enum nkNone, nkSlot, nkList, nkCase
|
||||
TNimNode {.codegenType.} = object
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue