mirror of
https://github.com/nim-lang/Nim.git
synced 2026-06-04 10:54:42 +00:00
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:
@@ -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) =
|
||||
|
||||
Reference in New Issue
Block a user