From affbe30b4188ab11417d156fe2d430f9c1a426b0 Mon Sep 17 00:00:00 2001 From: andri lim Date: Wed, 9 Oct 2019 08:51:53 +0700 Subject: [PATCH] implement compile time helpers --- stint/io.nim | 8 +++----- stint/private/compiletime_helpers.nim | 9 +++++++++ stint/private/endians2_priv.nim | 15 +++++---------- 3 files changed, 17 insertions(+), 15 deletions(-) create mode 100644 stint/private/compiletime_helpers.nim diff --git a/stint/io.nim b/stint/io.nim index 35aa61d..854bc8a 100644 --- a/stint/io.nim +++ b/stint/io.nim @@ -10,7 +10,7 @@ import ./private/datatypes, ./private/int_negabs, - ./private/[int_bitwise_ops, uint_bitwise_ops], + ./private/compiletime_helpers, ./intops, typetraits, algorithm @@ -285,13 +285,11 @@ proc dumpHex*(x: Stint or StUint, order: static[Endianness] = bigEndian): string result = newString(2*size) when nimvm: - type DT = type x.data.leastSignificantWord for i in 0 ..< size: when order == system.cpuEndian: - let pos = (i * 8) + let byte = x.data.getByte(i) else: - let pos = ((size - (i + 1)) * 8) - let byte = (x.data shr pos).leastSignificantWord and 0xFF.DT + let byte = x.data.getByte(size - 1 - i) result[2*i] = hexChars[int byte shr 4 and 0xF] result[2*i+1] = hexChars[int byte and 0xF] else: diff --git a/stint/private/compiletime_helpers.nim b/stint/private/compiletime_helpers.nim new file mode 100644 index 0000000..96eaec3 --- /dev/null +++ b/stint/private/compiletime_helpers.nim @@ -0,0 +1,9 @@ +import ./datatypes, ./uint_bitwise_ops + +func getByte*(x: SomeInteger, pos: int): byte {.compileTime.} = + type DT = type x + byte((x shr (pos * 8)) and 0xFF.DT) + +func getByte*(x: UintImpl | IntImpl, pos: int): byte {.compileTime.} = + type DT = type x.leastSignificantWord + byte((x shr (pos * 8)).leastSignificantWord and 0xFF.DT) diff --git a/stint/private/endians2_priv.nim b/stint/private/endians2_priv.nim index cf3a53e..812be23 100644 --- a/stint/private/endians2_priv.nim +++ b/stint/private/endians2_priv.nim @@ -1,5 +1,4 @@ -import ./bitops2_priv, ./datatypes, ./uint_bitwise_ops - +import ./bitops2_priv, ./datatypes, ./compiletime_helpers import stew/endians2 export endians2 @@ -9,25 +8,21 @@ func swapBytes*(x: UintImpl): UintImpl {.inline.} = UintImpl(hi: hi, lo: lo) -func copyMem(x: UintImpl): auto {.compileTime.} = +func copyMem(x: UintImpl, ret: var openArray[byte]) {.compileTime.} = const size = bitsof(x) div 8 - var ret: array[size, byte] - type DT = type x.leastSignificantWord for i in 0 ..< size: - let pos = i * 8 - ret[i] = byte((x shr pos).leastSignificantWord and 0xFF.DT) - ret + ret[i] = x.getByte(i) func toBytes*(x: UintImpl, endian: Endianness = system.cpuEndian): auto {.inline.} = # TODO can't use bitsof in return type (compiler bug?), hence return auto var ret: array[bitsof(x) div 8, byte] when nimvm: if endian == system.cpuEndian: - ret = copyMem(x) + copyMem(x, ret) else: let v = swapBytes(x) - ret = copyMem(v) + copyMem(v, ret) else: if endian == system.cpuEndian: copyMem(addr ret[0], unsafeAddr x, ret.len)