@effekt-lang/effekt 0.24.0 → 0.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/effekt +0 -0
- package/libraries/common/buffer.effekt +32 -33
- package/libraries/common/queue.effekt +62 -62
- package/libraries/common/stringbuffer.effekt +1 -1
- package/libraries/js/effekt_runtime.js +72 -69
- package/libraries/llvm/rts.ll +2 -30
- package/licenses/eclipse public license, version 2.0 - epl-2.0.html +23 -23
- package/licenses/mit license - mit-license.html +21 -19
- package/licenses/the bsd license - bsd-license.html +20 -20
- package/licenses/the mit license - mit.html +21 -19
- package/package.json +1 -1
package/bin/effekt
CHANGED
|
Binary file
|
|
@@ -3,7 +3,6 @@ module buffer
|
|
|
3
3
|
import array
|
|
4
4
|
|
|
5
5
|
// TODO (in Effekt compiler)
|
|
6
|
-
// - [ ] fix allocating into actually global region
|
|
7
6
|
// - [ ] fix exceptions on objects
|
|
8
7
|
// - [X] allow omitting braces after `at` for singleton regions
|
|
9
8
|
|
|
@@ -35,12 +34,12 @@ def emptyBuffer[T](capacity: Int): Buffer[T] at {global} = {
|
|
|
35
34
|
def arrayBuffer[T](initialCapacity: Int): Buffer[T] at {global} = {
|
|
36
35
|
// TODO allocate buffer (and array) into a region r.
|
|
37
36
|
val contents = array::allocate[T](initialCapacity)
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
val head = ref(0)
|
|
38
|
+
val tail = ref(0)
|
|
40
39
|
|
|
41
40
|
def size(): Int =
|
|
42
|
-
if (tail >= head) { tail - head }
|
|
43
|
-
else { initialCapacity - head + tail }
|
|
41
|
+
if (tail.get >= head.get) { tail.get - head.get }
|
|
42
|
+
else { initialCapacity - head.get + tail.get }
|
|
44
43
|
|
|
45
44
|
def capacity(): Int = initialCapacity - size()
|
|
46
45
|
|
|
@@ -51,36 +50,36 @@ def arrayBuffer[T](initialCapacity: Int): Buffer[T] at {global} = {
|
|
|
51
50
|
def read() = {
|
|
52
51
|
if (buffer.empty?) None()
|
|
53
52
|
else {
|
|
54
|
-
val result: T = contents.unsafeGet(head)
|
|
55
|
-
head
|
|
53
|
+
val result: T = contents.unsafeGet(head.get)
|
|
54
|
+
head.set(mod(head.get + 1, initialCapacity))
|
|
56
55
|
Some(result)
|
|
57
56
|
}
|
|
58
57
|
}
|
|
59
58
|
def write(el: T) = {
|
|
60
59
|
if (buffer.full?) <> // raise(BufferOverflow())
|
|
61
60
|
|
|
62
|
-
contents.unsafeSet(tail, el)
|
|
63
|
-
tail
|
|
61
|
+
contents.unsafeSet(tail.get, el)
|
|
62
|
+
tail.set(mod(tail.get + 1, initialCapacity))
|
|
64
63
|
}
|
|
65
64
|
}
|
|
66
65
|
buffer
|
|
67
66
|
}
|
|
68
67
|
def refBuffer[T](): Buffer[T] at {global} = {
|
|
69
|
-
|
|
68
|
+
val content = ref(None())
|
|
70
69
|
new Buffer[T] {
|
|
71
|
-
def capacity() = if (content.isEmpty) 1 else 0
|
|
72
|
-
def full?() = content.isDefined
|
|
73
|
-
def empty?() = isEmpty(content)
|
|
70
|
+
def capacity() = if (content.get.isEmpty) 1 else 0
|
|
71
|
+
def full?() = content.get.isDefined
|
|
72
|
+
def empty?() = isEmpty(content.get)
|
|
74
73
|
def read() = {
|
|
75
|
-
val res = content
|
|
76
|
-
content
|
|
74
|
+
val res = content.get
|
|
75
|
+
content.set(None())
|
|
77
76
|
res
|
|
78
77
|
}
|
|
79
|
-
def write(el: T) = content match {
|
|
78
|
+
def write(el: T) = content.get match {
|
|
80
79
|
case Some(v) =>
|
|
81
80
|
<> // do raise(BufferOverflow(), "Cannot read element from buffer")
|
|
82
81
|
case None() =>
|
|
83
|
-
content
|
|
82
|
+
content.set(Some(el))
|
|
84
83
|
}
|
|
85
84
|
}
|
|
86
85
|
}
|
|
@@ -88,24 +87,24 @@ def refBuffer[T](): Buffer[T] at {global} = {
|
|
|
88
87
|
namespace examples {
|
|
89
88
|
def main() = ignore[BufferOverflow] {
|
|
90
89
|
// Buffer with capacity 1
|
|
91
|
-
def b = emptyBuffer[Int](1)
|
|
92
|
-
println(b.capacity)
|
|
93
|
-
println(b.full?)
|
|
90
|
+
def b = emptyBuffer[Int](1)
|
|
91
|
+
println(b.capacity)
|
|
92
|
+
println(b.full?)
|
|
94
93
|
|
|
95
|
-
b.write(17)
|
|
96
|
-
println(b.read())
|
|
94
|
+
b.write(17)
|
|
95
|
+
println(b.read())
|
|
97
96
|
|
|
98
97
|
// buffer with capacity 3
|
|
99
|
-
def ringbuffer = emptyBuffer[Int](3)
|
|
100
|
-
ringbuffer.write(1)
|
|
101
|
-
ringbuffer.write(2)
|
|
102
|
-
println(ringbuffer.read())
|
|
103
|
-
ringbuffer.write(3)
|
|
104
|
-
println(ringbuffer.read())
|
|
105
|
-
println(ringbuffer.read())
|
|
106
|
-
ringbuffer.write(4)
|
|
107
|
-
ringbuffer.write(5)
|
|
108
|
-
println(ringbuffer.read())
|
|
109
|
-
println(ringbuffer.read())
|
|
98
|
+
def ringbuffer = emptyBuffer[Int](3)
|
|
99
|
+
ringbuffer.write(1)
|
|
100
|
+
ringbuffer.write(2)
|
|
101
|
+
println(ringbuffer.read())
|
|
102
|
+
ringbuffer.write(3)
|
|
103
|
+
println(ringbuffer.read())
|
|
104
|
+
println(ringbuffer.read())
|
|
105
|
+
ringbuffer.write(4)
|
|
106
|
+
ringbuffer.write(5)
|
|
107
|
+
println(ringbuffer.read())
|
|
108
|
+
println(ringbuffer.read())
|
|
110
109
|
}
|
|
111
110
|
}
|
|
@@ -25,82 +25,82 @@ def emptyQueue[T](): Queue[T] at {global} =
|
|
|
25
25
|
|
|
26
26
|
def emptyQueue[T](initialCapacity: Int): Queue[T] at {global} = {
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
val contents = ref(array[Option[T]](initialCapacity, None()))
|
|
29
|
+
val head = ref(0)
|
|
30
|
+
val tail = ref(0)
|
|
31
|
+
val size = ref(0)
|
|
32
|
+
val capacity = ref(initialCapacity)
|
|
33
33
|
|
|
34
34
|
def remove(arr: Array[Option[T]], index: Int): Option[T] = {
|
|
35
|
-
with on[OutOfBounds].default { None() }
|
|
36
|
-
val value = arr.get(index)
|
|
37
|
-
arr.set(index, None())
|
|
35
|
+
with on[OutOfBounds].default { None() }
|
|
36
|
+
val value = arr.get(index)
|
|
37
|
+
arr.set(index, None())
|
|
38
38
|
value
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
def nonEmpty[T] { p: => Option[T] / Exception[OutOfBounds] }: Option[T] =
|
|
42
|
-
if (size <= 0) None() else on[OutOfBounds].default { None() } { p() }
|
|
42
|
+
if (size.get <= 0) None() else on[OutOfBounds].default { None() } { p() }
|
|
43
43
|
|
|
44
44
|
// Exponential back-off
|
|
45
45
|
def resizeTo(requiredSize: Int): Unit =
|
|
46
|
-
if (requiredSize <= capacity) () else {
|
|
46
|
+
if (requiredSize <= capacity.get) () else {
|
|
47
47
|
with on[OutOfBounds].ignore // should not happen
|
|
48
48
|
|
|
49
|
-
val oldSize = capacity
|
|
50
|
-
val newSize = capacity * 2
|
|
51
|
-
val oldContents = contents
|
|
49
|
+
val oldSize = capacity.get
|
|
50
|
+
val newSize = capacity.get * 2
|
|
51
|
+
val oldContents = contents.get
|
|
52
52
|
val newContents = array::allocate[Option[T]](newSize)
|
|
53
53
|
|
|
54
|
-
if (head < tail) {
|
|
54
|
+
if (head.get < tail.get) {
|
|
55
55
|
// The queue does not wrap around; direct copy is possible.
|
|
56
|
-
copy(oldContents, head, newContents, 0, size) // changed tail to size
|
|
57
|
-
} else if (size > 0) {
|
|
56
|
+
copy(oldContents, head.get, newContents, 0, size.get) // changed tail to size
|
|
57
|
+
} else if (size.get > 0) {
|
|
58
58
|
// The queue wraps around; copy in two segments.
|
|
59
|
-
copy(oldContents, head, newContents, 0, oldSize - head) // changed oldSize to oldSize - head
|
|
60
|
-
copy(oldContents, 0, newContents, oldSize - head, tail) // changed oldSize - head to oldSize - head
|
|
59
|
+
copy(oldContents, head.get, newContents, 0, oldSize - head.get) // changed oldSize to oldSize - head
|
|
60
|
+
copy(oldContents, 0, newContents, oldSize - head.get, tail.get) // changed oldSize - head to oldSize - head
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
contents
|
|
64
|
-
capacity
|
|
65
|
-
head
|
|
66
|
-
tail
|
|
63
|
+
contents.set(newContents)
|
|
64
|
+
capacity.set(newSize)
|
|
65
|
+
head.set(0)
|
|
66
|
+
tail.set(oldSize)
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
def queue = new Queue[T] {
|
|
70
|
-
def empty?() = size <= 0
|
|
70
|
+
def empty?() = size.get <= 0
|
|
71
71
|
|
|
72
72
|
def popFront() =
|
|
73
73
|
nonEmpty {
|
|
74
|
-
val result = contents.remove(head)
|
|
75
|
-
head
|
|
76
|
-
size
|
|
74
|
+
val result = contents.get.remove(head.get)
|
|
75
|
+
head.set(mod(head.get + 1, capacity.get))
|
|
76
|
+
size.set(size.get - 1)
|
|
77
77
|
result
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
def popBack() =
|
|
81
81
|
nonEmpty {
|
|
82
|
-
tail
|
|
83
|
-
val result = contents.remove(tail)
|
|
84
|
-
size
|
|
82
|
+
tail.set(mod(tail.get - 1 + capacity.get, capacity.get))
|
|
83
|
+
val result = contents.get.remove(tail.get)
|
|
84
|
+
size.set(size.get - 1)
|
|
85
85
|
result
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
def peekFront() = nonEmpty { contents.get(head) }
|
|
88
|
+
def peekFront() = nonEmpty { contents.get.get(head.get) }
|
|
89
89
|
|
|
90
|
-
def peekBack() = nonEmpty { contents.get(tail) }
|
|
90
|
+
def peekBack() = nonEmpty { contents.get.get(tail.get) }
|
|
91
91
|
|
|
92
92
|
def pushFront(el: T) = {
|
|
93
|
-
resizeTo(size + 1)
|
|
94
|
-
head
|
|
95
|
-
size
|
|
96
|
-
contents.unsafeSet(head, Some(el))
|
|
93
|
+
resizeTo(size.get + 1)
|
|
94
|
+
head.set(mod(head.get - 1 + capacity.get, capacity.get))
|
|
95
|
+
size.set(size.get + 1)
|
|
96
|
+
contents.get.unsafeSet(head.get, Some(el))
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
def pushBack(el: T) = {
|
|
100
|
-
resizeTo(size + 1)
|
|
101
|
-
contents.unsafeSet(tail, Some(el))
|
|
102
|
-
size
|
|
103
|
-
tail
|
|
100
|
+
resizeTo(size.get + 1)
|
|
101
|
+
contents.get.unsafeSet(tail.get, Some(el))
|
|
102
|
+
size.set(size.get + 1)
|
|
103
|
+
tail.set(mod(tail.get + 1, capacity.get))
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
106
|
queue
|
|
@@ -109,30 +109,30 @@ def emptyQueue[T](initialCapacity: Int): Queue[T] at {global} = {
|
|
|
109
109
|
namespace examples {
|
|
110
110
|
def main() = {
|
|
111
111
|
// queue with initial capacity 4
|
|
112
|
-
def b = emptyQueue[Int](4)
|
|
113
|
-
println(b.empty?)
|
|
114
|
-
b.pushFront(1)
|
|
115
|
-
b.pushBack(2)
|
|
116
|
-
b.pushFront(3)
|
|
117
|
-
b.pushBack(4)
|
|
112
|
+
def b = emptyQueue[Int](4)
|
|
113
|
+
println(b.empty?)
|
|
114
|
+
b.pushFront(1)
|
|
115
|
+
b.pushBack(2)
|
|
116
|
+
b.pushFront(3)
|
|
117
|
+
b.pushBack(4)
|
|
118
118
|
// this will cause resizing:
|
|
119
|
-
b.pushBack(5)
|
|
120
|
-
b.pushBack(6)
|
|
121
|
-
b.pushBack(7)
|
|
122
|
-
b.pushBack(8)
|
|
119
|
+
b.pushBack(5)
|
|
120
|
+
b.pushBack(6)
|
|
121
|
+
b.pushBack(7)
|
|
122
|
+
b.pushBack(8)
|
|
123
123
|
// and again:
|
|
124
|
-
b.pushBack(9)
|
|
125
|
-
|
|
126
|
-
println(b.empty?)
|
|
127
|
-
println(b.popFront())
|
|
128
|
-
println(b.popFront())
|
|
129
|
-
println(b.popFront())
|
|
130
|
-
println(b.popFront())
|
|
131
|
-
println(b.popFront())
|
|
132
|
-
println(b.popFront())
|
|
133
|
-
println(b.popFront())
|
|
134
|
-
println(b.popFront())
|
|
135
|
-
println(b.popFront())
|
|
136
|
-
println(b.popFront())
|
|
124
|
+
b.pushBack(9)
|
|
125
|
+
|
|
126
|
+
println(b.empty?)
|
|
127
|
+
println(b.popFront()) // Some(3)
|
|
128
|
+
println(b.popFront()) // Some(1)
|
|
129
|
+
println(b.popFront()) // Some(2)
|
|
130
|
+
println(b.popFront()) // Some(4)
|
|
131
|
+
println(b.popFront()) // Some(5)
|
|
132
|
+
println(b.popFront()) // Some(6)
|
|
133
|
+
println(b.popFront()) // Some(7)
|
|
134
|
+
println(b.popFront()) // Some(8)
|
|
135
|
+
println(b.popFront()) // Some(9)
|
|
136
|
+
println(b.popFront()) // None()
|
|
137
137
|
}
|
|
138
138
|
}
|
|
@@ -14,7 +14,7 @@ def stringBuffer[A] { prog: => A / StringBuffer }: A = {
|
|
|
14
14
|
var pos = 0
|
|
15
15
|
|
|
16
16
|
def ensureCapacity(sizeToAdd: Int): Unit = {
|
|
17
|
-
val cap = buffer.size - pos
|
|
17
|
+
val cap = buffer.size - pos
|
|
18
18
|
if (sizeToAdd <= cap) ()
|
|
19
19
|
else {
|
|
20
20
|
// Double the capacity while ensuring the required capacity
|
|
@@ -1,69 +1,79 @@
|
|
|
1
|
-
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
|
|
1
|
+
// Complexity of state:
|
|
2
|
+
//
|
|
3
|
+
// get: O(1)
|
|
4
|
+
// set: O(1)
|
|
5
|
+
// capture: O(1)
|
|
6
|
+
// restore: O(|write operations since capture|)
|
|
7
|
+
const Mem = null
|
|
8
|
+
|
|
9
|
+
function Arena() {
|
|
10
|
+
const s = {
|
|
11
|
+
root: { value: Mem },
|
|
12
|
+
generation: 0,
|
|
13
|
+
fresh: (v) => {
|
|
14
|
+
const r = {
|
|
15
|
+
value: v,
|
|
16
|
+
generation: s.generation,
|
|
17
|
+
store: s,
|
|
18
|
+
set: (v) => {
|
|
19
|
+
const s = r.store
|
|
20
|
+
const r_gen = r.generation
|
|
21
|
+
const s_gen = s.generation
|
|
22
|
+
|
|
23
|
+
if (r_gen == s_gen) {
|
|
24
|
+
r.value = v;
|
|
25
|
+
} else {
|
|
26
|
+
const root = { value: Mem }
|
|
27
|
+
// update store
|
|
28
|
+
s.root.value = { ref: r, value: r.value, generation: r_gen, root: root }
|
|
29
|
+
s.root = root
|
|
30
|
+
r.value = v
|
|
31
|
+
r.generation = s_gen
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
return r
|
|
36
|
+
},
|
|
37
|
+
// not implemented
|
|
38
|
+
newRegion: () => s
|
|
39
|
+
};
|
|
40
|
+
return s
|
|
14
41
|
}
|
|
15
42
|
|
|
16
|
-
|
|
17
|
-
|
|
43
|
+
function snapshot(s) {
|
|
44
|
+
const snap = { store: s, root: s.root, generation: s.generation }
|
|
45
|
+
s.generation = s.generation + 1
|
|
46
|
+
return snap
|
|
18
47
|
}
|
|
19
48
|
|
|
20
|
-
function
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
// this doesn't work yet, since Arena.backup doesn't return a thunk
|
|
34
|
-
region.push(nested) //new WeakRef(nested))
|
|
35
|
-
return nested;
|
|
36
|
-
},
|
|
37
|
-
backup: function() {
|
|
38
|
-
const _backup = []
|
|
39
|
-
let nextIndex = 0;
|
|
40
|
-
for (const ref of region) {
|
|
41
|
-
const cell = ref //.deref()
|
|
42
|
-
// only backup live cells
|
|
43
|
-
if (cell) {
|
|
44
|
-
_backup[nextIndex] = cell.backup()
|
|
45
|
-
nextIndex++
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
function restore() {
|
|
49
|
-
const region = []
|
|
50
|
-
let nextIndex = 0;
|
|
51
|
-
for (const restoreCell of _backup) {
|
|
52
|
-
region[nextIndex] = restoreCell() // new WeakRef(restoreCell())
|
|
53
|
-
nextIndex++
|
|
54
|
-
}
|
|
55
|
-
return Arena(region)
|
|
56
|
-
}
|
|
57
|
-
return restore;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
49
|
+
function reroot(n) {
|
|
50
|
+
if (n.value === Mem) return;
|
|
51
|
+
|
|
52
|
+
const diff = n.value
|
|
53
|
+
const r = diff.ref
|
|
54
|
+
const v = diff.value
|
|
55
|
+
const g = diff.generation
|
|
56
|
+
const n2 = diff.root
|
|
57
|
+
reroot(n2)
|
|
58
|
+
n.value = Mem
|
|
59
|
+
n2.value = { ref: r, value: r.value, generation: r.generation, root: n}
|
|
60
|
+
r.value = v
|
|
61
|
+
r.generation = g
|
|
60
62
|
}
|
|
61
63
|
|
|
64
|
+
function restore(store, snap) {
|
|
65
|
+
// linear in the number of modifications...
|
|
66
|
+
reroot(snap.root)
|
|
67
|
+
store.root = snap.root
|
|
68
|
+
store.generation = snap.generation + 1
|
|
69
|
+
}
|
|
62
70
|
|
|
71
|
+
// Common Runtime
|
|
72
|
+
// --------------
|
|
63
73
|
let _prompt = 1;
|
|
64
74
|
|
|
65
75
|
const TOPLEVEL_K = (x, ks) => { throw { computationIsDone: true, result: x } }
|
|
66
|
-
const TOPLEVEL_KS = { prompt: 0, arena: Arena(
|
|
76
|
+
const TOPLEVEL_KS = { prompt: 0, arena: Arena(), rest: null }
|
|
67
77
|
|
|
68
78
|
function THUNK(f) {
|
|
69
79
|
f.thunk = true
|
|
@@ -80,9 +90,6 @@ function CAPTURE(body) {
|
|
|
80
90
|
|
|
81
91
|
const RETURN = (x, ks) => ks.rest.stack(x, ks.rest)
|
|
82
92
|
|
|
83
|
-
// const r = ks.arena.newRegion(); body
|
|
84
|
-
// const x = r.alloc(init); body
|
|
85
|
-
|
|
86
93
|
// HANDLE(ks, ks, (p, ks, k) => { STMT })
|
|
87
94
|
function RESET(prog, ks, k) {
|
|
88
95
|
const prompt = _prompt++;
|
|
@@ -90,13 +97,6 @@ function RESET(prog, ks, k) {
|
|
|
90
97
|
return prog(prompt, { prompt, arena: Arena([]), rest }, RETURN)
|
|
91
98
|
}
|
|
92
99
|
|
|
93
|
-
function DEALLOC(ks) {
|
|
94
|
-
const arena = ks.arena
|
|
95
|
-
if (!!arena) {
|
|
96
|
-
arena.length = arena.length - 1
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
100
|
function SHIFT(p, body, ks, k) {
|
|
101
101
|
|
|
102
102
|
// TODO avoid constructing this object
|
|
@@ -104,13 +104,15 @@ function SHIFT(p, body, ks, k) {
|
|
|
104
104
|
let cont = null
|
|
105
105
|
|
|
106
106
|
while (!!meta && meta.prompt !== p) {
|
|
107
|
-
|
|
107
|
+
let store = meta.arena
|
|
108
|
+
cont = { stack: meta.stack, prompt: meta.prompt, arena: store, backup: snapshot(store), rest: cont }
|
|
108
109
|
meta = meta.rest
|
|
109
110
|
}
|
|
110
111
|
if (!meta) { throw `Prompt not found ${p}` }
|
|
111
112
|
|
|
112
113
|
// package the prompt itself
|
|
113
|
-
|
|
114
|
+
let store = meta.arena
|
|
115
|
+
cont = { stack: meta.stack, prompt: meta.prompt, arena: store, backup: snapshot(store), rest: cont }
|
|
114
116
|
meta = meta.rest
|
|
115
117
|
|
|
116
118
|
const k1 = meta.stack
|
|
@@ -123,7 +125,8 @@ function RESUME(cont, c, ks, k) {
|
|
|
123
125
|
let meta = { stack: k, prompt: ks.prompt, arena: ks.arena, rest: ks.rest }
|
|
124
126
|
let toRewind = cont
|
|
125
127
|
while (!!toRewind) {
|
|
126
|
-
|
|
128
|
+
restore(toRewind.arena, toRewind.backup)
|
|
129
|
+
meta = { stack: toRewind.stack, prompt: toRewind.prompt, arena: toRewind.arena, rest: meta }
|
|
127
130
|
toRewind = toRewind.rest
|
|
128
131
|
}
|
|
129
132
|
|
package/libraries/llvm/rts.ll
CHANGED
|
@@ -678,14 +678,7 @@ define private void @freeStack(%StackPointer %stackPointer) alwaysinline {
|
|
|
678
678
|
; RTS initialization
|
|
679
679
|
|
|
680
680
|
define private tailcc void @topLevel(%Pos %val, %Stack %stack) {
|
|
681
|
-
|
|
682
|
-
; rest holds global variables
|
|
683
|
-
call void @resume_Pos(%Stack %rest, %Pos %val)
|
|
684
|
-
ret void
|
|
685
|
-
}
|
|
686
|
-
|
|
687
|
-
define private tailcc void @globalsReturn(%Pos %val, %Stack %stack) {
|
|
688
|
-
%rest = call %Stack @underflowStack(%Stack %stack)
|
|
681
|
+
call %Stack @underflowStack(%Stack %stack)
|
|
689
682
|
ret void
|
|
690
683
|
}
|
|
691
684
|
|
|
@@ -699,29 +692,8 @@ define private void @topLevelEraser(%Environment %environment) {
|
|
|
699
692
|
ret void
|
|
700
693
|
}
|
|
701
694
|
|
|
702
|
-
@global = private global { i64, %Stack } { i64 0, %Stack null }
|
|
703
|
-
|
|
704
695
|
define private %Stack @withEmptyStack() {
|
|
705
|
-
%
|
|
706
|
-
|
|
707
|
-
%globalsStackPointer_pointer = getelementptr %StackValue, %Stack %globals, i64 0, i32 1
|
|
708
|
-
%globalsStackPointer = load %StackPointer, ptr %globalsStackPointer_pointer, !alias.scope !11, !noalias !21
|
|
709
|
-
|
|
710
|
-
%returnAddressPointer.0 = getelementptr %FrameHeader, %StackPointer %globalsStackPointer, i64 0, i32 0
|
|
711
|
-
%sharerPointer.0 = getelementptr %FrameHeader, %StackPointer %globalsStackPointer, i64 0, i32 1
|
|
712
|
-
%eraserPointer.0 = getelementptr %FrameHeader, %StackPointer %globalsStackPointer, i64 0, i32 2
|
|
713
|
-
|
|
714
|
-
store ptr @globalsReturn, ptr %returnAddressPointer.0, !alias.scope !12, !noalias !22
|
|
715
|
-
store ptr @topLevelSharer, ptr %sharerPointer.0, !alias.scope !12, !noalias !22
|
|
716
|
-
store ptr @topLevelEraser, ptr %eraserPointer.0, !alias.scope !12, !noalias !22
|
|
717
|
-
|
|
718
|
-
%globalsStackPointer_2 = getelementptr %FrameHeader, %StackPointer %globalsStackPointer, i64 1
|
|
719
|
-
store %StackPointer %globalsStackPointer_2, ptr %globalsStackPointer_pointer, !alias.scope !11, !noalias !21
|
|
720
|
-
|
|
721
|
-
%stack = call %Stack @reset(%Stack %globals)
|
|
722
|
-
|
|
723
|
-
%globalStack = getelementptr %PromptValue, %Prompt @global, i64 0, i32 1
|
|
724
|
-
store %Stack %stack, ptr %globalStack, !alias.scope !13, !noalias !23
|
|
696
|
+
%stack = call %Stack @reset(%Stack null)
|
|
725
697
|
|
|
726
698
|
%stackStackPointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 1
|
|
727
699
|
%stackPointer = load %StackPointer, ptr %stackStackPointer, !alias.scope !11, !noalias !21
|