From 0b06077c55413edafb1210d385f313d980008031 Mon Sep 17 00:00:00 2001 From: andri lim Date: Tue, 8 Oct 2019 20:40:27 +0700 Subject: [PATCH] compile time toBytes --- stint/private/endians2_priv.nim | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/stint/private/endians2_priv.nim b/stint/private/endians2_priv.nim index 8abf73f..cf3a53e 100644 --- a/stint/private/endians2_priv.nim +++ b/stint/private/endians2_priv.nim @@ -1,4 +1,4 @@ -import ./bitops2_priv, ./datatypes +import ./bitops2_priv, ./datatypes, ./uint_bitwise_ops import stew/endians2 export endians2 @@ -9,13 +9,29 @@ func swapBytes*(x: UintImpl): UintImpl {.inline.} = UintImpl(hi: hi, lo: lo) +func copyMem(x: UintImpl): auto {.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 + func toBytes*(x: UintImpl, endian: Endianness = system.cpuEndian): auto {.inline.} = # TODO can't use bitsof in return type (compiler bug?), hence return auto - # TODO compile-time version var ret: array[bitsof(x) div 8, byte] - if endian == system.cpuEndian: - copyMem(addr ret[0], unsafeAddr x, ret.len) + when nimvm: + if endian == system.cpuEndian: + ret = copyMem(x) + else: + let v = swapBytes(x) + ret = copyMem(v) else: - let v = swapBytes(x) - copyMem(addr ret[0], unsafeAddr v, ret.len) + if endian == system.cpuEndian: + copyMem(addr ret[0], unsafeAddr x, ret.len) + else: + let v = swapBytes(x) + copyMem(addr ret[0], unsafeAddr v, ret.len) ret