From b1df02b245af7df0ff877916487867a1a0c5bff0 Mon Sep 17 00:00:00 2001 From: Araq Date: Fri, 29 Nov 2019 16:43:45 +0100 Subject: [PATCH] fixes #12669 --- compiler/dfa.nim | 37 ++++++++++---- tests/destructor/tarray_indexing.nim | 75 ++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 11 deletions(-) create mode 100644 tests/destructor/tarray_indexing.nim diff --git a/compiler/dfa.nim b/compiler/dfa.nim index c97e39460b87e..cc0b8f7ae46e1 100644 --- a/compiler/dfa.nim +++ b/compiler/dfa.nim @@ -572,16 +572,6 @@ const nkObjDownConv, nkObjUpConv} PathKinds1 = {nkHiddenStdConv, nkHiddenSubConv} -proc getRoot(n: PNode): PNode = - result = n - while true: - case result.kind - of PathKinds0: - result = result[0] - of PathKinds1: - result = result[1] - else: break - proc skipConvDfa*(n: PNode): PNode = result = n while true: @@ -593,7 +583,17 @@ proc skipConvDfa*(n: PNode): PNode = else: break proc genUse(c: var Con; orig: PNode) = - let n = dfa.getRoot(orig) + var n = orig + while true: + case n.kind + of PathKinds0 - {nkBracketExpr}: + n = n[0] + of nkBracketExpr: + gen(c, n[1]) + n = n[0] + of PathKinds1: + n = n[1] + else: break if n.kind == nkSym and n.sym.kind in InterestingSyms: c.code.add Instr(n: orig, kind: use, sym: if orig != n: nil else: n.sym) @@ -673,6 +673,21 @@ proc isAnalysableFieldAccess*(orig: PNode; owner: PSym): bool = # lower level C++ optimizer to specialize this code. proc genDef(c: var Con; n: PNode) = + var m = n + # XXX do something about this duplicated logic here. + while true: + case m.kind + of nkDotExpr, nkCheckedFieldExpr, nkHiddenSubConv, nkHiddenStdConv, + nkObjDownConv, nkObjUpConv, nkHiddenAddr, nkAddr: + m = m[0] + of nkBracketExpr: + gen(c, m[1]) + m = m[0] + of nkHiddenDeref, nkDerefExpr: + m = m[0] + else: + break + if n.kind == nkSym and n.sym.kind in InterestingSyms: c.code.add Instr(n: n, kind: def, sym: n.sym) elif isAnalysableFieldAccess(n, c.owner): diff --git a/tests/destructor/tarray_indexing.nim b/tests/destructor/tarray_indexing.nim new file mode 100644 index 0000000000000..7efd5a00c8e98 --- /dev/null +++ b/tests/destructor/tarray_indexing.nim @@ -0,0 +1,75 @@ +discard """ + output: '''allocating 1048576 65536 +filling page from 1048576 len 65536''' + cmd: '''nim c --newruntime $file''' +""" + +# bug #12669 + +type + MemState* = enum + memPrivate + + MemPermisison* = enum + memperm_Read + + MemInfo* = ref object + base*, size*: uint32 + state*: MemState + perm*: set[MemPermisison] + + MemBlock = ref object + info: MemInfo + data: seq[byte] + + UserProcessMemory* = ref object + pageAccess: array[0x40000, ptr UncheckedArray[byte]] + pages: array[0x40000, MemInfo] + blocks: seq[owned MemBlock] + +proc allocMemory*(mem: UserProcessMemory, base, size: uint32) = + let + roundedBase = base and not(0xFFF'u32) + roundedSize = (size + 0xFFF) and not(0xFFF'u32) + + echo "allocating ", base, " ", size + for i in (roundedBase shr 12)..<((roundedBase + roundedSize) shr 12): + #echo "span ", i + doAssert mem.pages[i] == nil + # TODO: beserer fehler + + let memBlock = MemBlock( + info: MemInfo( + base: roundedBase, + size: roundedSize, + state: memPrivate, + perm: {memperm_Read} + ), + data: newSeq[byte](roundedSize)) + for i in 0..<(roundedSize shr 12): + mem.pages[i + (roundedBase shr 12)] = memBlock.info + #echo cast[uint64](addr mem.pageAccess[i + (roundedBase shr 12)]) + mem.pageAccess[i + (roundedBase shr 12)] = cast[ptr UncheckedArray[byte]](addr memBlock.data[i * 0x1000]) + mem.blocks.add memBlock + + #for i in (roundedBase shr 12)..<((roundedBase + roundedSize) shr 12): + # assert mem.pageAccess[i] != nil + +proc fillPages*(mem: UserProcessMemory, start: uint32, data: seq[byte]) = + echo "filling page from ", start, " len ", data.len + assert (start and not(0xFFF'u32)) == start + assert (uint32(data.len) and not(0xFFF'u32)) == uint32(data.len) + for i in (start shr 12)..<((start + uint32(data.len)) shr 12): + #echo cast[uint64](addr mem.pageAccess[i]) + let page = mem.pageAccess[i] + assert page != nil + #copyMem(page, unsafeAddr data[i * 0x1000 - start], 0x1000) + +const base = 0x00100000 + +proc a(): owned UserProcessMemory = + result = UserProcessMemory() + result.allocMemory(base, 0x1000 * 16) + result.fillPages(base, newSeq[byte](0x1000 * 16)) + +discard a()