summary refs log tree commit diff stats
path: root/tests/js/taddr.nim
blob: 9c45621a8dced5d6119c21fb8d558835f2128fc8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
discard """
  targets: "c js"
"""

type T = object
  x: int
  s: string

var obj: T
var fieldAddr = addr(obj.x)
var objAddr = addr(obj)

# Integer tests
var field = fieldAddr[]
doAssert field == 0

var objDeref = objAddr[]
doAssert objDeref.x == 0

# Change value
obj.x = 42

doAssert field == 0
doAssert objDeref.x == 0

field = fieldAddr[]
objDeref = objAddr[]

doAssert field == 42
doAssert objDeref.x == 42

# String tests
obj.s = "lorem ipsum dolor sit amet"
var indexAddr = addr(obj.s[2])

doAssert indexAddr[] == 'r'

indexAddr[] = 'd'

doAssert indexAddr[] == 'd'

doAssert obj.s == "lodem ipsum dolor sit amet"

# Bug #2148
var x: array[2, int]
var y = addr x[1]

y[] = 12
doAssert(x[1] == 12)

type
  Foo = object
    bar: int

var foo: array[2, Foo]
var z = addr foo[1]

z[].bar = 12345
doAssert(foo[1].bar == 12345)

var t : tuple[a, b: int]
var pt = addr t[1]
pt[] = 123
doAssert(t.b == 123)

#block: # Test "untyped" pointer.
proc testPtr(p: pointer, a: int) =
  doAssert(a == 5)
  (cast[ptr int](p))[] = 124
var i = 123
testPtr(addr i, 5)
doAssert(i == 124)

var someGlobal = 5
proc getSomeGlobalPtr(): ptr int = addr someGlobal
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]