Make the swap procs safe for unaligned input ptrs (#9210)

* Make the swap procs safe for unaligned input ptrs

The copy to a temporary local variable is often elided by a sufficiently
smart compiler when it can prove the input pointer is aligned.

Refs #9206

* Explain why copyMem is used

(cherry picked from commit 1fe949b9d5)
This commit is contained in:
LemonBoy
2018-10-18 14:30:31 +02:00
committed by narimiran
parent 624d05c73f
commit 8a356fafb7

View File

@@ -44,20 +44,23 @@ else:
const useBuiltinSwap = false
when useBuiltinSwap:
template swapOpImpl(T: typedesc, op: untyped) =
## We have to use `copyMem` here instead of a simple deference because they
## may point to a unaligned address. A sufficiently smart compiler _should_
## be able to elide them when they're not necessary.
var tmp: T
copyMem(addr tmp, inp, sizeOf(T))
tmp = op(tmp)
copyMem(outp, addr tmp, sizeOf(T))
proc swapEndian64*(outp, inp: pointer) {.inline, nosideeffect.}=
var i = cast[ptr uint64](inp)
var o = cast[ptr uint64](outp)
o[] = builtin_bswap64(i[])
swapOpImpl(uint64, builtin_bswap64)
proc swapEndian32*(outp, inp: pointer) {.inline, nosideeffect.}=
var i = cast[ptr uint32](inp)
var o = cast[ptr uint32](outp)
o[] = builtin_bswap32(i[])
swapOpImpl(uint32, builtin_bswap32)
proc swapEndian16*(outp, inp: pointer) {.inline, nosideeffect.}=
var i = cast[ptr uint16](inp)
var o = cast[ptr uint16](outp)
o[] = builtin_bswap16(i[])
swapOpImpl(uint16, builtin_bswap16)
else:
proc swapEndian64*(outp, inp: pointer) =