diff --git a/compiler/vm.nim b/compiler/vm.nim index 9e5db978cf..7f0dd80edc 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -622,6 +622,13 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = stackTrace(c, tos, pc, errNilAccess) regs[ra].nodeAddr[][] = n[] regs[ra].nodeAddr[].flags.incl nfIsRef + # `var object` parameters are sent as rkNodeAddr. When they are mutated + # vmgen generates opcWrDeref, which means that we must dereference + # twice. + # TODO: This should likely be handled differently in vmgen. + elif (nfIsRef notin regs[ra].nodeAddr[].flags and + nfIsRef notin n.flags): + regs[ra].nodeAddr[][] = n[] else: regs[ra].nodeAddr[] = n of rkRegisterAddr: regs[ra].regAddr[] = regs[rc] diff --git a/tests/vm/tvmmisc.nim b/tests/vm/tvmmisc.nim index d82c2cf5e2..6a8084647f 100644 --- a/tests/vm/tvmmisc.nim +++ b/tests/vm/tvmmisc.nim @@ -135,3 +135,16 @@ static: o.pushName() o.pushName() doAssert o.names == "FOOBARFOOBAR" + +# #8154 +import parseutils + +static: + type Obj = object + i: int + + proc foo(): Obj = + discard parseInt("1", result.i, 0) + + static: + doAssert foo().i == 1