diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/core/typeinfo.nim | 1 | ||||
-rw-r--r-- | lib/system.nim | 3 | ||||
-rw-r--r-- | lib/system/assign.nim | 16 | ||||
-rw-r--r-- | lib/system/channels.nim | 2 | ||||
-rw-r--r-- | lib/system/deepcopy.nim | 2 | ||||
-rw-r--r-- | lib/system/gc.nim | 12 | ||||
-rw-r--r-- | lib/system/gc2.nim | 10 | ||||
-rw-r--r-- | lib/system/gc_ms.nim | 8 | ||||
-rw-r--r-- | lib/system/hti.nim | 15 |
9 files changed, 51 insertions, 18 deletions
diff --git a/lib/core/typeinfo.nim b/lib/core/typeinfo.nim index 72b139202..0f3639f0d 100644 --- a/lib/core/typeinfo.nim +++ b/lib/core/typeinfo.nim @@ -54,6 +54,7 @@ type akUInt16 = 42, ## any represents an unsigned in16 akUInt32 = 43, ## any represents an unsigned int32 akUInt64 = 44, ## any represents an unsigned int64 + akOpt = 44+18 ## the builtin 'opt' type. Any* = object ## can represent any nim value; NOTE: the wrapped ## value can be modified with its wrapper! This means diff --git a/lib/system.nim b/lib/system.nim index 61d79bac3..e642eb335 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -246,6 +246,9 @@ type UncheckedArray* {.unchecked.}[T] = array[0, T] ## Array with no bounds checking +when defined(nimHasOpt): + type opt*{.magic: "Opt".}[T] + proc high*[T: Ordinal](x: T): T {.magic: "High", noSideEffect.} ## returns the highest possible index of an array, a sequence, a string or ## the highest possible value of an ordinal value `x`. As a special diff --git a/lib/system/assign.nim b/lib/system/assign.nim index 61c33e51b..01261d4b5 100644 --- a/lib/system/assign.nim +++ b/lib/system/assign.nim @@ -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) diff --git a/lib/system/channels.nim b/lib/system/channels.nim index 1b90e245f..df6c6d41e 100644 --- a/lib/system/channels.nim +++ b/lib/system/channels.nim @@ -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: diff --git a/lib/system/deepcopy.nim b/lib/system/deepcopy.nim index 65ba2278c..51e138e5e 100644 --- a/lib/system/deepcopy.nim +++ b/lib/system/deepcopy.nim @@ -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) diff --git a/lib/system/gc.nim b/lib/system/gc.nim index 80aa5cf1b..13778ee5e 100644 --- a/lib/system/gc.nim +++ b/lib/system/gc.nim @@ -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") diff --git a/lib/system/gc2.nim b/lib/system/gc2.nim index 68da65727..55d515d0b 100644 --- a/lib/system/gc2.nim +++ b/lib/system/gc2.nim @@ -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") diff --git a/lib/system/gc_ms.nim b/lib/system/gc_ms.nim index e03140d05..494c32b1a 100644 --- a/lib/system/gc_ms.nim +++ b/lib/system/gc_ms.nim @@ -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") diff --git a/lib/system/hti.nim b/lib/system/hti.nim index 69f4f9508..45b1d1cd3 100644 --- a/lib/system/hti.nim +++ b/lib/system/hti.nim @@ -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 |