* fix #14576 addr(param) now works in nim js * workaround https://github.com/nim-lang/Nim/issues/14578
This commit is contained in:
parent
336f1e63d0
commit
61f2f1f5c5
3 changed files with 71 additions and 3 deletions
|
|
@ -141,6 +141,7 @@ proc genSetNode(p: BProc, n: PNode): Rope =
|
||||||
result = genRawSetData(cs, size)
|
result = genRawSetData(cs, size)
|
||||||
|
|
||||||
proc getStorageLoc(n: PNode): TStorageLoc =
|
proc getStorageLoc(n: PNode): TStorageLoc =
|
||||||
|
## deadcode
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkSym:
|
of nkSym:
|
||||||
case n.sym.kind
|
case n.sym.kind
|
||||||
|
|
|
||||||
|
|
@ -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])
|
lineF(p, "var $1 = $4; $2 = $1[0]; $3 = $1[1];$n", [tmp, a.address, a.res, b.rdLoc])
|
||||||
elif b.typ == etyBaseIndex:
|
elif b.typ == etyBaseIndex:
|
||||||
lineF(p, "$# = [$#, $#];$n", [a.res, b.address, b.res])
|
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:
|
else:
|
||||||
internalError(p.config, x.info, "genAsgn")
|
internalError(p.config, x.info, $("genAsgn", b.typ, a.typ))
|
||||||
else:
|
else:
|
||||||
lineF(p, "$1 = $2; $3 = $4;$n", [a.address, b.address, a.res, b.res])
|
lineF(p, "$1 = $2; $3 = $4;$n", [a.address, b.address, a.res, b.res])
|
||||||
else:
|
else:
|
||||||
|
|
@ -1266,6 +1269,10 @@ proc genAddr(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
let s = n[0].sym
|
let s = n[0].sym
|
||||||
if s.loc.r == nil: internalError(p.config, n.info, "genAddr: 3")
|
if s.loc.r == nil: internalError(p.config, n.info, "genAddr: 3")
|
||||||
case s.kind
|
case s.kind
|
||||||
|
of skParam:
|
||||||
|
r.res = s.loc.r
|
||||||
|
r.address = nil
|
||||||
|
r.typ = etyNone
|
||||||
of skVar, skLet, skResult:
|
of skVar, skLet, skResult:
|
||||||
r.kind = resExpr
|
r.kind = resExpr
|
||||||
let jsType = mapType(p, n.typ)
|
let jsType = mapType(p, n.typ)
|
||||||
|
|
@ -1287,7 +1294,7 @@ proc genAddr(p: PProc, n: PNode, r: var TCompRes) =
|
||||||
# 'var openArray' for instance produces an 'addr' but this is harmless:
|
# 'var openArray' for instance produces an 'addr' but this is harmless:
|
||||||
gen(p, n[0], r)
|
gen(p, n[0], r)
|
||||||
#internalError(p.config, n.info, "genAddr: 4 " & renderTree(n))
|
#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:
|
of nkCheckedFieldExpr:
|
||||||
genCheckedFieldOp(p, n[0], n.typ, r)
|
genCheckedFieldOp(p, n[0], n.typ, r)
|
||||||
of nkDotExpr:
|
of nkDotExpr:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
discard """
|
discard """
|
||||||
action: run
|
targets: "c js"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
type T = object
|
type T = object
|
||||||
|
|
@ -77,3 +77,63 @@ let someGlobalPtr = getSomeGlobalPtr()
|
||||||
doAssert(someGlobalPtr[] == 5)
|
doAssert(someGlobalPtr[] == 5)
|
||||||
someGlobalPtr[] = 10
|
someGlobalPtr[] = 10
|
||||||
doAssert(someGlobal == 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]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue