Skip to content

Commit

Permalink
fix #14576 addr of param (including for lent) now works with nim js (#…
Browse files Browse the repository at this point in the history
…14577)

* fix #14576 addr(param) now works in nim js

* workaround #14578
  • Loading branch information
timotheecour authored Jun 6, 2020
1 parent 336f1e6 commit 61f2f1f
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 3 deletions.
1 change: 1 addition & 0 deletions compiler/ccgexprs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ proc genSetNode(p: BProc, n: PNode): Rope =
result = genRawSetData(cs, size)

proc getStorageLoc(n: PNode): TStorageLoc =
## deadcode
case n.kind
of nkSym:
case n.sym.kind
Expand Down
11 changes: 9 additions & 2 deletions compiler/jsgen.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1065,8 +1065,11 @@ proc genAsgnAux(p: PProc, x, y: PNode, noCopyNeeded: bool) =
lineF(p, "var $1 = $4; $2 = $1[0]; $3 = $1[1];$n", [tmp, a.address, a.res, b.rdLoc])
elif b.typ == etyBaseIndex:
lineF(p, "$# = [$#, $#];$n", [a.res, b.address, b.res])
elif b.typ == etyNone:
internalAssert p.config, b.address == nil
lineF(p, "$# = [$#, 0];$n", [a.address, b.res])
else:
internalError(p.config, x.info, "genAsgn")
internalError(p.config, x.info, $("genAsgn", b.typ, a.typ))
else:
lineF(p, "$1 = $2; $3 = $4;$n", [a.address, b.address, a.res, b.res])
else:
Expand Down Expand Up @@ -1266,6 +1269,10 @@ proc genAddr(p: PProc, n: PNode, r: var TCompRes) =
let s = n[0].sym
if s.loc.r == nil: internalError(p.config, n.info, "genAddr: 3")
case s.kind
of skParam:
r.res = s.loc.r
r.address = nil
r.typ = etyNone
of skVar, skLet, skResult:
r.kind = resExpr
let jsType = mapType(p, n.typ)
Expand All @@ -1287,7 +1294,7 @@ proc genAddr(p: PProc, n: PNode, r: var TCompRes) =
# 'var openArray' for instance produces an 'addr' but this is harmless:
gen(p, n[0], r)
#internalError(p.config, n.info, "genAddr: 4 " & renderTree(n))
else: internalError(p.config, n.info, "genAddr: 2")
else: internalError(p.config, n.info, $("genAddr: 2", s.kind))
of nkCheckedFieldExpr:
genCheckedFieldOp(p, n[0], n.typ, r)
of nkDotExpr:
Expand Down
62 changes: 61 additions & 1 deletion tests/js/taddr.nim
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
discard """
action: run
targets: "c js"
"""

type T = object
Expand Down Expand Up @@ -77,3 +77,63 @@ let someGlobalPtr = getSomeGlobalPtr()
doAssert(someGlobalPtr[] == 5)
someGlobalPtr[] = 10
doAssert(someGlobal == 10)

block:
# issue #14576
# lots of these used to give: Error: internal error: genAddr: 2
proc byLent[T](a: T): lent T = a
proc byPtr[T](a: T): ptr T = a.unsafeAddr

block:
let a = (10,11)
let (x,y) = byLent(a)
doAssert (x,y) == a

block:
when defined(c) and defined(release):
# bug; pending https://github.com/nim-lang/Nim/issues/14578
discard
else:
let a = 10
doAssert byLent(a) == 10
let a2 = byLent(a)
doAssert a2 == 10

block:
let a = [11,12]
doAssert byLent(a) == [11,12]
let a2 = (11,)
doAssert byLent(a2) == (11,)

block:
when defined(c) and defined(release):
discard # probably not a bug since optimizer is free to pass by value, and `unsafeAddr` is used
else:
var a = @[12]
doAssert byPtr(a)[] == @[12]
let a2 = [13]
doAssert byPtr(a2)[] == [13]
let a3 = 14
doAssert byPtr(a3)[] == 14

block:
proc byLent2[T](a: seq[T]): lent T = a[1]
var a = @[20,21,22]
doAssert byLent2(a) == 21

block: # sanity checks
proc bar[T](a: var T): var T = a
var a = (10, 11)
let (k,v) = bar(a)
doAssert (k, v) == a
doAssert k == 10
bar(a)[0]+=100
doAssert a == (110, 11)
var a2 = 12
doAssert bar(a2) == a2
bar(a2).inc
doAssert a2 == 13

block: # xxx: bug this doesn't work
when false:
proc byLent2[T](a: T): lent type(a[0]) = a[0]

0 comments on commit 61f2f1f

Please sign in to comment.