Skip to content

Commit

Permalink
fixes #12669
Browse files Browse the repository at this point in the history
  • Loading branch information
Araq committed Nov 29, 2019
1 parent 007a3a8 commit b1df02b
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 11 deletions.
37 changes: 26 additions & 11 deletions compiler/dfa.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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)

Expand Down Expand Up @@ -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):
Expand Down
75 changes: 75 additions & 0 deletions tests/destructor/tarray_indexing.nim
Original file line number Diff line number Diff line change
@@ -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()

0 comments on commit b1df02b

Please sign in to comment.