workaround `--mm:orc` codegen bug with `{.noSideEffect.}` (#63)

Inlining `template` that uses `{.noSideEffect.}` without a `block` can
lead to invalid codegen that contains double-frees. Wrap problematic
instances with `block` to prevent issues in `libnimbus_lc` wasm (orc).
This commit is contained in:
Etan Kissling 2023-10-27 15:12:07 +02:00 committed by GitHub
parent 4bdbc29e54
commit 543b2f3dd0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 40 additions and 37 deletions

View File

@ -8,19 +8,20 @@ export
template encode*(Format: type, value: auto, params: varargs[untyped]): auto = template encode*(Format: type, value: auto, params: varargs[untyped]): auto =
mixin init, Writer, writeValue, PreferredOutputType mixin init, Writer, writeValue, PreferredOutputType
{.noSideEffect.}: block: # https://github.com/nim-lang/Nim/issues/22874
# We assume that there is no side-effects here, because we are {.noSideEffect.}:
# using a `memoryOutput`. The computed side-effects are coming # We assume that there is no side-effects here, because we are
# from the fact that the dynamic dispatch mechanisms used in # using a `memoryOutput`. The computed side-effects are coming
# faststreams may be writing to a file or a network device. # from the fact that the dynamic dispatch mechanisms used in
try: # faststreams may be writing to a file or a network device.
var s = memoryOutput() try:
type WriterType = Writer(Format) var s = memoryOutput()
var writer = unpackArgs(init, [WriterType, s, params]) type WriterType = Writer(Format)
writeValue writer, value var writer = unpackArgs(init, [WriterType, s, params])
s.getOutput PreferredOutputType(Format) writeValue writer, value
except IOError: s.getOutput PreferredOutputType(Format)
raise (ref Defect)() # a memoryOutput cannot have an IOError except IOError:
raise (ref Defect)() # a memoryOutput cannot have an IOError
# TODO Nim cannot make sense of this initialization by var param? # TODO Nim cannot make sense of this initialization by var param?
proc readValue*(reader: var auto, T: type): T {.gcsafe, raises: [SerializationError, IOError].} = proc readValue*(reader: var auto, T: type): T {.gcsafe, raises: [SerializationError, IOError].} =
@ -37,18 +38,19 @@ template decode*(Format: distinct type,
# TODO, this is dusplicated only due to a Nim bug: # TODO, this is dusplicated only due to a Nim bug:
# If `input` was `string|openArray[byte]`, it won't match `seq[byte]` # If `input` was `string|openArray[byte]`, it won't match `seq[byte]`
mixin init, Reader mixin init, Reader
{.noSideEffect.}: block: # https://github.com/nim-lang/Nim/issues/22874
# We assume that there are no side-effects here, because we are {.noSideEffect.}:
# using a `memoryInput`. The computed side-effects are coming # We assume that there are no side-effects here, because we are
# from the fact that the dynamic dispatch mechanisms used in # using a `memoryInput`. The computed side-effects are coming
# faststreams may be reading from a file or a network device. # from the fact that the dynamic dispatch mechanisms used in
try: # faststreams may be reading from a file or a network device.
var stream = unsafeMemoryInput(input) try:
type ReaderType = Reader(Format) var stream = unsafeMemoryInput(input)
var reader = unpackArgs(init, [ReaderType, stream, params]) type ReaderType = Reader(Format)
reader.readValue(RecordType) var reader = unpackArgs(init, [ReaderType, stream, params])
except IOError: reader.readValue(RecordType)
raise (ref Defect)() # memory inputs cannot raise an IOError except IOError:
raise (ref Defect)() # memory inputs cannot raise an IOError
template decode*(Format: distinct type, template decode*(Format: distinct type,
input: openArray[byte], input: openArray[byte],
@ -57,18 +59,19 @@ template decode*(Format: distinct type,
# TODO, this is dusplicated only due to a Nim bug: # TODO, this is dusplicated only due to a Nim bug:
# If `input` was `string|openArray[byte]`, it won't match `seq[byte]` # If `input` was `string|openArray[byte]`, it won't match `seq[byte]`
mixin init, Reader mixin init, Reader
{.noSideEffect.}: block: # https://github.com/nim-lang/Nim/issues/22874
# We assume that there are no side-effects here, because we are {.noSideEffect.}:
# using a `memoryInput`. The computed side-effects are coming # We assume that there are no side-effects here, because we are
# from the fact that the dynamic dispatch mechanisms used in # using a `memoryInput`. The computed side-effects are coming
# faststreams may be reading from a file or a network device. # from the fact that the dynamic dispatch mechanisms used in
try: # faststreams may be reading from a file or a network device.
var stream = unsafeMemoryInput(input) try:
type ReaderType = Reader(Format) var stream = unsafeMemoryInput(input)
var reader = unpackArgs(init, [ReaderType, stream, params]) type ReaderType = Reader(Format)
reader.readValue(RecordType) var reader = unpackArgs(init, [ReaderType, stream, params])
except IOError: reader.readValue(RecordType)
raise (ref Defect)() # memory inputs cannot raise an IOError except IOError:
raise (ref Defect)() # memory inputs cannot raise an IOError
template loadFile*(Format: distinct type, template loadFile*(Format: distinct type,
filename: string, filename: string,