diff options
Diffstat (limited to 'lib/system/repr.nim')
-rw-r--r-- | lib/system/repr.nim | 164 |
1 files changed, 91 insertions, 73 deletions
diff --git a/lib/system/repr.nim b/lib/system/repr.nim index 1f81a0813..13118e40b 100644 --- a/lib/system/repr.nim +++ b/lib/system/repr.nim @@ -16,40 +16,24 @@ proc reprInt(x: int64): string {.compilerproc.} = return $x proc reprFloat(x: float): string {.compilerproc.} = return $x proc reprPointer(x: pointer): string {.compilerproc.} = - var buf: array [0..59, char] - discard c_sprintf(buf, "%p", x) - return $buf + result = newString(60) + let n = c_snprintf(cast[cstring](addr result[0]), csize_t(60), "%p", x) + setLen(result, n) -proc `$`(x: uint64): string = - if x == 0: - result = "0" - else: - var buf: array [60, char] - var i = 0 - var n = x - while n != 0: - let nn = n div 10'u64 - buf[i] = char(n - 10'u64 * nn + ord('0')) - inc i - n = nn - - let half = i div 2 - # Reverse - for t in 0 .. < half: swap(buf[t], buf[i-t-1]) - result = $buf - -proc reprStrAux(result: var string, s: string) = +proc reprStrAux(result: var string, s: cstring; len: int) = if cast[pointer](s) == nil: add result, "nil" return - add result, reprPointer(cast[pointer](s)) & "\"" - for i in 0.. <s.len: + if len > 0: + add result, reprPointer(cast[pointer](s)) + add result, "\"" + for i in 0 .. pred(len): let c = s[i] case c of '"': add result, "\\\"" of '\\': add result, "\\\\" # BUGFIX: forgotten of '\10': add result, "\\10\"\n\"" # " \n " # better readability - of '\128' .. '\255', '\0'..'\9', '\11'..'\31': + of '\127' .. '\255', '\0'..'\9', '\11'..'\31': add result, "\\" & reprInt(ord(c)) else: result.add(c) @@ -57,7 +41,7 @@ proc reprStrAux(result: var string, s: string) = proc reprStr(s: string): string {.compilerRtl.} = result = "" - reprStrAux(result, s) + reprStrAux(result, s, s.len) proc reprBool(x: bool): string {.compilerRtl.} = if x: result = "true" @@ -68,30 +52,30 @@ proc reprChar(x: char): string {.compilerRtl.} = case x of '"': add result, "\\\"" of '\\': add result, "\\\\" - of '\128' .. '\255', '\0'..'\31': add result, "\\" & reprInt(ord(x)) + of '\127' .. '\255', '\0'..'\31': add result, "\\" & reprInt(ord(x)) else: add result, x add result, "\'" proc reprEnum(e: int, typ: PNimType): string {.compilerRtl.} = - # we read an 'int' but this may have been too large, so mask the other bits: - let e = if typ.size == 1: e and 0xff - elif typ.size == 2: e and 0xffff - else: e - # XXX we need a proper narrowing based on signedness here - #e and ((1 shl (typ.size*8)) - 1) + ## Return string representation for enumeration values + var n = typ.node if ntfEnumHole notin typ.flags: - if e <% typ.node.len: - return $typ.node.sons[e].name + let o = e - n.sons[0].offset + if o >= 0 and o <% typ.node.len: + return $n.sons[o].name else: # ugh we need a slow linear search: - var n = typ.node var s = n.sons for i in 0 .. n.len-1: - if s[i].offset == e: return $s[i].name + if s[i].offset == e: + return $s[i].name + result = $e & " (invalid data!)" +include system/repr_impl + type - PByteArray = ptr array[0.. 0xffff, int8] + PByteArray = ptr UncheckedArray[byte] # array[0xffff, byte] proc addSetElem(result: var string, elem: int, typ: PNimType) {.benign.} = case typ.kind @@ -108,22 +92,23 @@ proc reprSetAux(result: var string, p: pointer, typ: PNimType) = var elemCounter = 0 # we need this flag for adding the comma at # the right places add result, "{" - var u: int64 + var u: uint64 case typ.size - of 1: u = ze64(cast[ptr int8](p)[]) - of 2: u = ze64(cast[ptr int16](p)[]) - of 4: u = ze64(cast[ptr int32](p)[]) - of 8: u = cast[ptr int64](p)[] + of 1: u = cast[ptr uint8](p)[] + of 2: u = cast[ptr uint16](p)[] + of 4: u = cast[ptr uint32](p)[] + of 8: u = cast[ptr uint64](p)[] else: + u = uint64(0) var a = cast[PByteArray](p) for i in 0 .. typ.size*8-1: - if (ze(a[i div 8]) and (1 shl (i mod 8))) != 0: + if (uint(a[i shr 3]) and (1'u shl (i and 7))) != 0: if elemCounter > 0: add result, ", " addSetElem(result, i+typ.node.len, typ.base) inc(elemCounter) if typ.size <= 8: for i in 0..sizeof(int64)*8-1: - if (u and (1'i64 shl int64(i))) != 0'i64: + if (u and (1'u64 shl uint64(i))) != 0'u64: if elemCounter > 0: add result, ", " addSetElem(result, i+typ.node.len, typ.base) inc(elemCounter) @@ -140,7 +125,6 @@ type marked: CellSet recdepth: int # do not recurse endlessly indent: int # indentation -{.deprecated: [TReprClosure: ReprClosure].} when not defined(useNimRtl): proc initReprClosure(cl: var ReprClosure) = @@ -171,19 +155,35 @@ when not defined(useNimRtl): var bs = typ.base.size for i in 0..typ.size div bs - 1: if i > 0: add result, ", " - reprAux(result, cast[pointer](cast[ByteAddress](p) + i*bs), typ.base, cl) + reprAux(result, cast[pointer](cast[int](p) + i*bs), typ.base, cl) add result, "]" + when defined(nimSeqsV2): + type + GenericSeq = object + len: int + p: pointer + PGenericSeq = ptr GenericSeq + const payloadOffset = sizeof(int) + sizeof(pointer) + # see seqs.nim: cap: int + # region: Allocator + + template payloadPtr(x: untyped): untyped = cast[PGenericSeq](x).p + else: + const payloadOffset = GenericSeqSize ## the payload offset always depends on the alignment of the member type. + template payloadPtr(x: untyped): untyped = x + proc reprSequence(result: var string, p: pointer, typ: PNimType, cl: var ReprClosure) = if p == nil: - add result, "nil" + add result, "[]" return - result.add(reprPointer(p) & "[") + result.add(reprPointer(p)) + result.add "@[" var bs = typ.base.size for i in 0..cast[PGenericSeq](p).len-1: if i > 0: add result, ", " - reprAux(result, cast[pointer](cast[ByteAddress](p) + GenericSeqSize + i*bs), + reprAux(result, cast[pointer](cast[int](payloadPtr(p)) + align(payloadOffset, typ.align) + i*bs), typ.base, cl) add result, "]" @@ -194,14 +194,14 @@ when not defined(useNimRtl): of nkSlot: add result, $n.name add result, " = " - reprAux(result, cast[pointer](cast[ByteAddress](p) + n.offset), n.typ, cl) + reprAux(result, cast[pointer](cast[int](p) + n.offset), n.typ, cl) of nkList: for i in 0..n.len-1: if i > 0: add result, ",\n" reprRecordAux(result, p, n.sons[i], cl) of nkCase: var m = selectBranch(p, n) - reprAux(result, cast[pointer](cast[ByteAddress](p) + n.offset), n.typ, cl) + reprAux(result, cast[pointer](cast[int](p) + n.offset), n.typ, cl) if m != nil: reprRecordAux(result, p, m, cl) proc reprRecord(result: var string, p: pointer, typ: PNimType, @@ -224,17 +224,26 @@ when not defined(useNimRtl): cl: var ReprClosure) = # we know that p is not nil here: when declared(CellSet): - when defined(boehmGC) or defined(gogc) or defined(nogc): + when defined(boehmGC) or defined(gogc) or defined(nogc) or usesDestructors: var cell = cast[PCell](p) else: var cell = usrToCell(p) - add result, "ref " & reprPointer(p) + add result, if typ.kind == tyPtr: "ptr " else: "ref " + add result, reprPointer(p) if cell notin cl.marked: # only the address is shown: incl(cl.marked, cell) add result, " --> " reprAux(result, p, typ.base, cl) + proc getInt(p: pointer, size: int): int = + case size + of 1: return int(cast[ptr uint8](p)[]) + of 2: return int(cast[ptr uint16](p)[]) + of 4: return int(cast[ptr uint32](p)[]) + of 8: return int(cast[ptr uint64](p)[]) + else: discard + proc reprAux(result: var string, p: pointer, typ: PNimType, cl: var ReprClosure) = if cl.recdepth == 0: @@ -259,40 +268,48 @@ when not defined(useNimRtl): of tyInt16: add result, $int(cast[ptr int16](p)[]) of tyInt32: add result, $int(cast[ptr int32](p)[]) of tyInt64: add result, $(cast[ptr int64](p)[]) - of tyUInt8: add result, $ze(cast[ptr int8](p)[]) - of tyUInt16: add result, $ze(cast[ptr int16](p)[]) + of tyUInt: add result, $(cast[ptr uint](p)[]) + of tyUInt8: add result, $(cast[ptr uint8](p)[]) + of tyUInt16: add result, $(cast[ptr uint16](p)[]) + of tyUInt32: add result, $(cast[ptr uint32](p)[]) + of tyUInt64: add result, $(cast[ptr uint64](p)[]) of tyFloat: add result, $(cast[ptr float](p)[]) of tyFloat32: add result, $(cast[ptr float32](p)[]) of tyFloat64: add result, $(cast[ptr float64](p)[]) - of tyEnum: add result, reprEnum(cast[ptr int](p)[], typ) + of tyEnum: add result, reprEnum(getInt(p, typ.size), typ) of tyBool: add result, reprBool(cast[ptr bool](p)[]) of tyChar: add result, reprChar(cast[ptr char](p)[]) - of tyString: reprStrAux(result, cast[ptr string](p)[]) - of tyCString: + of tyString: + let sp = cast[ptr string](p) + reprStrAux(result, sp[].cstring, sp[].len) + of tyCstring: let cs = cast[ptr cstring](p)[] if cs.isNil: add result, "nil" - else: reprStrAux(result, $cs) + else: reprStrAux(result, cs, cs.len) of tyRange: reprAux(result, p, typ.base, cl) of tyProc, tyPointer: if cast[PPointer](p)[] == nil: add result, "nil" else: add result, reprPointer(cast[PPointer](p)[]) + of tyUncheckedArray: + add result, "[...]" else: add result, "(invalid data!)" inc(cl.recdepth) -proc reprOpenArray(p: pointer, length: int, elemtyp: PNimType): string {. - compilerRtl.} = - var - cl: ReprClosure - initReprClosure(cl) - result = "[" - var bs = elemtyp.size - for i in 0..length - 1: - if i > 0: add result, ", " - reprAux(result, cast[pointer](cast[ByteAddress](p) + i*bs), elemtyp, cl) - add result, "]" - deinitReprClosure(cl) +when not defined(useNimRtl): + proc reprOpenArray(p: pointer, length: int, elemtyp: PNimType): string {. + compilerRtl.} = + var + cl: ReprClosure + initReprClosure(cl) + result = "[" + var bs = elemtyp.size + for i in 0..length - 1: + if i > 0: add result, ", " + reprAux(result, cast[pointer](cast[int](p) + i*bs), elemtyp, cl) + add result, "]" + deinitReprClosure(cl) when not defined(useNimRtl): proc reprAny(p: pointer, typ: PNimType): string = @@ -305,5 +322,6 @@ when not defined(useNimRtl): else: var p = p reprAux(result, addr(p), typ, cl) - add result, "\n" + when defined(nimLegacyReprWithNewline): # see PR #16034 + add result, "\n" deinitReprClosure(cl) |