Skip to content

Commit

Permalink
fixes #16771; lower swap for JS backend (#23473)
Browse files Browse the repository at this point in the history
fixes #16771

follow up #16536

Ideally it should be handled in the IR part in the future

I have also checked the double evaluation of `swap` in the JS runtime
#16779, that might be solved by a
copy flag or something. Well, it should be best solved in the IR so that
it doesn't bother backends anymore.
  • Loading branch information
ringabout authored Apr 3, 2024
1 parent dee55f5 commit 9e1b170
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 16 deletions.
17 changes: 4 additions & 13 deletions compiler/jsgen.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1322,19 +1322,10 @@ proc genFastAsgn(p: PProc, n: PNode) =
genAsgnAux(p, n[0], n[1], noCopyNeeded=noCopy)

proc genSwap(p: PProc, n: PNode) =
var a, b: TCompRes = default(TCompRes)
gen(p, n[1], a)
gen(p, n[2], b)
var tmp = p.getTemp(false)
if mapType(p, skipTypes(n[1].typ, abstractVar)) == etyBaseIndex:
let tmp2 = p.getTemp(false)
if a.typ != etyBaseIndex or b.typ != etyBaseIndex:
internalError(p.config, n.info, "genSwap")
lineF(p, "var $1 = $2; $2 = $3; $3 = $1;$n",
[tmp, a.address, b.address])
tmp = tmp2
lineF(p, "var $1 = $2; $2 = $3; $3 = $1;",
[tmp, a.res, b.res])
let stmtList = lowerSwap(p.module.graph, n, p.module.idgen, if p.prc != nil: p.prc else: p.module.module)
assert stmtList.kind == nkStmtList
for i in 0..<stmtList.len:
genStmt(p, stmtList[i])

proc getFieldPosition(p: PProc; f: PNode): int =
case f.kind
Expand Down
4 changes: 1 addition & 3 deletions lib/pure/collections/lists.nim
Original file line number Diff line number Diff line change
Expand Up @@ -384,9 +384,7 @@ proc prependMoved*[T: SomeLinkedList](a, b: var T) {.since: (1, 5, 1).} =
assert s == [0, 1, 0, 1, 0, 1]

b.addMoved(a)
when defined(js): # XXX: swap broken in js; bug #16771
(b, a) = (a, b)
else: swap a, b
swap a, b

proc add*[T](L: var SinglyLinkedList[T], n: SinglyLinkedNode[T]) {.inline.} =
## Appends (adds to the end) a node `n` to `L`. Efficiency: O(1).
Expand Down
19 changes: 19 additions & 0 deletions tests/stdlib/tmisc_issues.nim
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,22 @@ type

var x: Object = Object(data: Test(Data(id: 12)))
doAssert Data(x.data).id == 12

block: # bug #16771
type A = object
n: int

proc foo(a, b: var A) =
swap a, b

var a, b: A
a.n = 42
b.n = 1
doAssert a.n == 42
doAssert b.n == 1
a.swap b
doAssert a.n == 1
doAssert b.n == 42
a.foo b
doAssert a.n == 42
doAssert b.n == 1

0 comments on commit 9e1b170

Please sign in to comment.