@effekt-lang/effekt 0.2.2 → 0.4.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/README.md +6 -18
- package/bin/effekt +0 -0
- package/bin/effekt.sh +1 -1
- package/libraries/chez/common/effekt_primitives.ss +10 -2
- package/libraries/chez/common/immutable/cslist.effekt +13 -7
- package/libraries/chez/common/mutable/dict.effekt +8 -10
- package/libraries/chez/common/text/regex.effekt +7 -9
- package/libraries/common/args.effekt +68 -0
- package/libraries/common/array.effekt +220 -0
- package/libraries/common/bench.effekt +86 -0
- package/libraries/common/buffer.effekt +123 -0
- package/libraries/common/bytes.effekt +125 -0
- package/libraries/{js/immutable → common}/dequeue.effekt +18 -4
- package/libraries/common/effekt.effekt +725 -0
- package/libraries/common/exception.effekt +121 -0
- package/libraries/common/io/console.effekt +62 -0
- package/libraries/common/io/error.effekt +474 -0
- package/libraries/common/io/filesystem.effekt +274 -0
- package/libraries/common/io/network.effekt +81 -0
- package/libraries/common/io/time.effekt +12 -0
- package/libraries/common/io.effekt +88 -0
- package/libraries/{llvm/immutable → common}/list.effekt +101 -74
- package/libraries/common/option.effekt +72 -0
- package/libraries/common/process.effekt +9 -0
- package/libraries/common/queue.effekt +140 -0
- package/libraries/common/ref.effekt +60 -0
- package/libraries/common/result.effekt +45 -0
- package/libraries/{ml/immutable → common}/seq.effekt +30 -19
- package/libraries/common/string/tty.effekt +66 -0
- package/libraries/common/string.effekt +361 -0
- package/libraries/common/test.effekt +160 -0
- package/libraries/js/effekt_builtins.js +37 -6
- package/libraries/js/mutable/map.effekt +8 -9
- package/libraries/js/text/regex.effekt +7 -8
- package/libraries/js/unsafe/cont.effekt +2 -2
- package/libraries/js/web/dom.effekt +13 -13
- package/libraries/llvm/array.c +53 -0
- package/libraries/llvm/buffer.c +181 -76
- package/libraries/llvm/forward-declare-c.ll +27 -8
- package/libraries/llvm/io.c +423 -1
- package/libraries/llvm/main.c +6 -1
- package/libraries/llvm/ref.c +45 -0
- package/libraries/llvm/rts.ll +515 -354
- package/libraries/llvm/types.c +32 -0
- package/licenses/eclipse public license, version 2.0 - epl-2.0.html +4 -4
- package/licenses/mit license - mit-license.html +532 -62
- package/licenses/the bsd license - bsd-license.html +535 -60
- package/licenses/the mit license - mit.html +532 -62
- package/package.json +2 -2
- package/libraries/chez/callcc/effekt.effekt +0 -221
- package/libraries/chez/common/effekt_matching.ss +0 -100
- package/libraries/chez/common/immutable/dequeue.effekt +0 -78
- package/libraries/chez/common/immutable/list.effekt +0 -643
- package/libraries/chez/common/immutable/option.effekt +0 -39
- package/libraries/chez/common/immutable/result.effekt +0 -29
- package/libraries/chez/common/io/args.effekt +0 -20
- package/libraries/chez/common/mutable/array.effekt +0 -27
- package/libraries/chez/common/mutable/heap.effekt +0 -12
- package/libraries/chez/common/test.effekt +0 -59
- package/libraries/chez/common/text/string.effekt +0 -46
- package/libraries/chez/lift/effekt.effekt +0 -217
- package/libraries/chez/lift/effekt.ss +0 -118
- package/libraries/chez/monadic/effekt.effekt +0 -218
- package/libraries/js/effekt.effekt +0 -284
- package/libraries/js/effekt_matching.js +0 -79
- package/libraries/js/immutable/list.effekt +0 -643
- package/libraries/js/immutable/option.effekt +0 -49
- package/libraries/js/immutable/result.effekt +0 -29
- package/libraries/js/io/args.effekt +0 -9
- package/libraries/js/io/async.effekt +0 -28
- package/libraries/js/io/async.js +0 -2
- package/libraries/js/io/file.effekt +0 -50
- package/libraries/js/io/file_include.js +0 -13
- package/libraries/js/mutable/array.effekt +0 -98
- package/libraries/js/mutable/heap.effekt +0 -32
- package/libraries/js/test.effekt +0 -59
- package/libraries/js/text/string.effekt +0 -64
- package/libraries/llvm/effekt.effekt +0 -243
- package/libraries/llvm/immutable/option.effekt +0 -53
- package/libraries/llvm/immutable/result.effekt +0 -29
- package/libraries/llvm/io/args.effekt +0 -24
- package/libraries/llvm/text/string.effekt +0 -179
- package/libraries/ml/effekt.effekt +0 -267
- package/libraries/ml/effekt.sml +0 -63
- package/libraries/ml/immutable/dequeue.effekt +0 -81
- package/libraries/ml/immutable/list.effekt +0 -674
- package/libraries/ml/immutable/option.effekt +0 -53
- package/libraries/ml/immutable/result.effekt +0 -29
- package/libraries/ml/internal/option.effekt +0 -18
- package/libraries/ml/io/args.effekt +0 -41
- package/libraries/ml/mutable/array.effekt +0 -43
- package/libraries/ml/random.effekt +0 -85
- package/libraries/ml/test.effekt +0 -60
- package/libraries/ml/text/regex.effekt +0 -107
- package/libraries/ml/text/string.effekt +0 -81
package/libraries/llvm/rts.ll
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
; Run-Time System
|
|
2
2
|
|
|
3
|
+
%Evidence = type i64
|
|
4
|
+
|
|
3
5
|
; Basic types
|
|
4
6
|
|
|
5
|
-
%
|
|
7
|
+
%Environment = type ptr
|
|
6
8
|
|
|
7
9
|
; Reference counts
|
|
8
|
-
%
|
|
10
|
+
%ReferenceCount = type i64
|
|
9
11
|
|
|
10
12
|
; Code to share (bump rc) an environment
|
|
11
13
|
%Sharer = type ptr
|
|
@@ -14,21 +16,21 @@
|
|
|
14
16
|
%Eraser = type ptr
|
|
15
17
|
|
|
16
18
|
; Every heap object starts with a header
|
|
17
|
-
%Header = type {%
|
|
19
|
+
%Header = type {%ReferenceCount, %Eraser}
|
|
18
20
|
|
|
19
21
|
; A heap object is a pointer to a header followed by payload.
|
|
20
22
|
;
|
|
21
|
-
; +--[ Header ]
|
|
22
|
-
; |
|
|
23
|
-
;
|
|
24
|
-
%
|
|
23
|
+
; +--[ Header ]--------------+-------------+
|
|
24
|
+
; | ReferenceCount | Eraser | Payload ... |
|
|
25
|
+
; +-----------------+--------+-------------+
|
|
26
|
+
%Object = type ptr
|
|
25
27
|
|
|
26
28
|
|
|
27
29
|
; A Frame has the following layout
|
|
28
30
|
;
|
|
29
|
-
; +-------[ FrameHeader ]
|
|
30
|
-
; |
|
|
31
|
-
;
|
|
31
|
+
; +-------[ FrameHeader ]------------+--------------+
|
|
32
|
+
; | ReturnAddress | Sharer | Eraser | Payload ... |
|
|
33
|
+
; +----------------------------------+--------------+
|
|
32
34
|
|
|
33
35
|
; A stack pointer points to the top-most frame followed by all other frames.
|
|
34
36
|
;
|
|
@@ -36,7 +38,7 @@
|
|
|
36
38
|
;
|
|
37
39
|
; +--------------------+ <- Limit
|
|
38
40
|
; : :
|
|
39
|
-
; : : <-
|
|
41
|
+
; : : <- StackPointer
|
|
40
42
|
; +--------------------+
|
|
41
43
|
; | FrameHeader |
|
|
42
44
|
; | z |
|
|
@@ -47,14 +49,14 @@
|
|
|
47
49
|
; +--------------------+
|
|
48
50
|
; : ... :
|
|
49
51
|
; +--------------------+ <- Base
|
|
50
|
-
%
|
|
51
|
-
%Base = type %
|
|
52
|
-
%Limit = type %
|
|
53
|
-
%
|
|
54
|
-
%FrameHeader = type { %
|
|
52
|
+
%StackPointer = type ptr
|
|
53
|
+
%Base = type %StackPointer
|
|
54
|
+
%Limit = type %StackPointer
|
|
55
|
+
%ReturnAddress = type ptr
|
|
56
|
+
%FrameHeader = type { %ReturnAddress, %Sharer, %Eraser }
|
|
55
57
|
|
|
56
58
|
; Pointers for a heap allocated stack
|
|
57
|
-
%
|
|
59
|
+
%Memory = type { %StackPointer, %Base, %Limit }
|
|
58
60
|
|
|
59
61
|
; The garbage collector differentiates three groups of types:
|
|
60
62
|
; - Values (Integer, Double)
|
|
@@ -62,63 +64,43 @@
|
|
|
62
64
|
; - Strings
|
|
63
65
|
; For each group we have an arena where mutable state is allocated.
|
|
64
66
|
;
|
|
65
|
-
%Region = type [ 3 x %
|
|
67
|
+
%Region = type [ 3 x %Memory ]
|
|
68
|
+
|
|
69
|
+
; The "meta" stack (a stack of stacks) -- a pointer to a %StackValue
|
|
70
|
+
%Stack = type ptr
|
|
66
71
|
|
|
67
|
-
;
|
|
68
|
-
%
|
|
72
|
+
; Unique tags to index into the stack.
|
|
73
|
+
%Prompt = type i64
|
|
74
|
+
|
|
75
|
+
; fresh prompt generation
|
|
76
|
+
@lastPrompt = private global %Prompt 0
|
|
69
77
|
|
|
70
78
|
; This is used for two purposes:
|
|
71
79
|
; - a refied first-class list of stacks (cyclic linked-list)
|
|
72
80
|
; - as part of an intrusive linked-list of stacks (meta stack)
|
|
73
|
-
%
|
|
74
|
-
|
|
75
|
-
; Positive data types consist of a (type-local) tag and a heap object
|
|
76
|
-
%Pos = type {i64, %Obj}
|
|
77
|
-
%Boolean = type %Pos
|
|
78
|
-
%Unit = type %Pos
|
|
79
|
-
|
|
80
|
-
; Negative types (codata) consist of a vtable and a heap object
|
|
81
|
-
%Neg = type {ptr, %Obj}
|
|
81
|
+
%StackValue = type { %ReferenceCount, %Memory, %Region, %Prompt, %Stack }
|
|
82
82
|
|
|
83
|
-
; Offset within the arena
|
|
84
|
-
%Ref = type i64
|
|
85
83
|
|
|
86
|
-
; Global locations
|
|
87
84
|
|
|
88
|
-
@base = private global %Base null
|
|
89
|
-
@limit = private global %Limit null
|
|
90
|
-
@region = private global %Region zeroinitializer
|
|
91
|
-
@rest = private global %Stk undef
|
|
92
85
|
|
|
86
|
+
; Positive data types consist of a (type-local) tag and a heap object
|
|
87
|
+
%Pos = type {i64, %Object}
|
|
93
88
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
%limit = load %Limit, ptr @limit
|
|
97
|
-
%region = load %Region, ptr @region
|
|
98
|
-
%rest = load %Stk, ptr @rest
|
|
89
|
+
; Negative types (codata) consist of a vtable and a heap object
|
|
90
|
+
%Neg = type {ptr, %Object}
|
|
99
91
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
%stk.2 = insertvalue %StkVal %stk.1, %Base %base, 1, 1
|
|
103
|
-
%stk.3 = insertvalue %StkVal %stk.2, %Limit %limit, 1, 2
|
|
104
|
-
%stk.4 = insertvalue %StkVal %stk.3, %Region %region, 2
|
|
105
|
-
%stk.5 = insertvalue %StkVal %stk.4, %Stk %rest, 3
|
|
92
|
+
; Reference into an arena (prompt -- cast to 32bit, offset 32bit)
|
|
93
|
+
%Reference = type {i32, i32}
|
|
106
94
|
|
|
107
|
-
|
|
108
|
-
}
|
|
95
|
+
; Builtin Types
|
|
109
96
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
store %Limit %limit, ptr @limit
|
|
118
|
-
store %Region %region, ptr @region
|
|
119
|
-
store %Stk %rest, ptr @rest
|
|
120
|
-
ret void
|
|
121
|
-
}
|
|
97
|
+
%Int = type i64
|
|
98
|
+
%Double = type double
|
|
99
|
+
%Byte = type i8
|
|
100
|
+
%Char = type i64
|
|
101
|
+
%Bool = type %Pos
|
|
102
|
+
%Unit = type %Pos
|
|
103
|
+
%String = type %Pos
|
|
122
104
|
|
|
123
105
|
; Foreign imports
|
|
124
106
|
|
|
@@ -128,37 +110,57 @@ declare ptr @realloc(ptr, i64)
|
|
|
128
110
|
declare void @memcpy(ptr, ptr, i64)
|
|
129
111
|
declare i64 @llvm.ctlz.i64 (i64 , i1)
|
|
130
112
|
declare i64 @llvm.fshr.i64(i64, i64, i64)
|
|
113
|
+
declare double @llvm.sqrt.f64(double)
|
|
114
|
+
declare double @llvm.round.f64(double)
|
|
115
|
+
declare double @llvm.ceil.f64(double)
|
|
116
|
+
declare double @llvm.floor.f64(double)
|
|
131
117
|
declare void @print(i64)
|
|
132
118
|
declare void @exit(i64)
|
|
133
119
|
|
|
120
|
+
|
|
121
|
+
; Prompts
|
|
122
|
+
|
|
123
|
+
define private %Prompt @currentPrompt(%Stack %stack) {
|
|
124
|
+
%prompt_pointer = getelementptr %StackValue, ptr %stack, i64 0, i32 3
|
|
125
|
+
%prompt = load %Prompt, ptr %prompt_pointer
|
|
126
|
+
ret %Prompt %prompt
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
define private %Prompt @freshPrompt() {
|
|
130
|
+
%currentPrompt = load %Prompt, ptr @lastPrompt
|
|
131
|
+
%newPrompt = add %Prompt %currentPrompt, 1
|
|
132
|
+
store %Prompt %newPrompt, ptr @lastPrompt
|
|
133
|
+
ret %Prompt %newPrompt
|
|
134
|
+
}
|
|
135
|
+
|
|
134
136
|
; Garbage collection
|
|
135
137
|
|
|
136
|
-
define %
|
|
138
|
+
define private %Object @newObject(%Eraser %eraser, i64 %environmentSize) alwaysinline {
|
|
137
139
|
; This magical 16 is the size of the object header
|
|
138
|
-
%size = add i64 %
|
|
139
|
-
%
|
|
140
|
-
%
|
|
141
|
-
%
|
|
142
|
-
store %
|
|
143
|
-
store %Eraser %eraser, ptr %
|
|
144
|
-
ret %
|
|
140
|
+
%size = add i64 %environmentSize, 16
|
|
141
|
+
%object = call ptr @malloc(i64 %size)
|
|
142
|
+
%objectReferenceCount = getelementptr %Header, ptr %object, i64 0, i32 0
|
|
143
|
+
%objectEraser = getelementptr %Header, ptr %object, i64 0, i32 1
|
|
144
|
+
store %ReferenceCount 0, ptr %objectReferenceCount
|
|
145
|
+
store %Eraser %eraser, ptr %objectEraser
|
|
146
|
+
ret %Object %object
|
|
145
147
|
}
|
|
146
148
|
|
|
147
|
-
define %
|
|
149
|
+
define private %Environment @objectEnvironment(%Object %object) alwaysinline {
|
|
148
150
|
; Environment is stored right after header
|
|
149
|
-
%
|
|
150
|
-
ret %
|
|
151
|
+
%environment = getelementptr %Header, ptr %object, i64 1
|
|
152
|
+
ret %Environment %environment
|
|
151
153
|
}
|
|
152
154
|
|
|
153
|
-
define void @shareObject(%
|
|
154
|
-
%
|
|
155
|
-
br i1 %
|
|
155
|
+
define private void @shareObject(%Object %object) alwaysinline {
|
|
156
|
+
%isNull = icmp eq %Object %object, null
|
|
157
|
+
br i1 %isNull, label %done, label %next
|
|
156
158
|
|
|
157
159
|
next:
|
|
158
|
-
%
|
|
159
|
-
%
|
|
160
|
-
%
|
|
161
|
-
store %
|
|
160
|
+
%objectReferenceCount = getelementptr %Header, ptr %object, i64 0, i32 0
|
|
161
|
+
%referenceCount = load %ReferenceCount, ptr %objectReferenceCount
|
|
162
|
+
%referenceCount.1 = add %ReferenceCount %referenceCount, 1
|
|
163
|
+
store %ReferenceCount %referenceCount.1, ptr %objectReferenceCount
|
|
162
164
|
br label %done
|
|
163
165
|
|
|
164
166
|
done:
|
|
@@ -166,37 +168,37 @@ define void @shareObject(%Obj %obj) alwaysinline {
|
|
|
166
168
|
}
|
|
167
169
|
|
|
168
170
|
define void @sharePositive(%Pos %val) alwaysinline {
|
|
169
|
-
%
|
|
170
|
-
tail call void @shareObject(%
|
|
171
|
+
%object = extractvalue %Pos %val, 1
|
|
172
|
+
tail call void @shareObject(%Object %object)
|
|
171
173
|
ret void
|
|
172
174
|
}
|
|
173
175
|
|
|
174
176
|
define void @shareNegative(%Neg %val) alwaysinline {
|
|
175
|
-
%
|
|
176
|
-
tail call void @shareObject(%
|
|
177
|
+
%object = extractvalue %Neg %val, 1
|
|
178
|
+
tail call void @shareObject(%Object %object)
|
|
177
179
|
ret void
|
|
178
180
|
}
|
|
179
181
|
|
|
180
|
-
define void @eraseObject(%
|
|
181
|
-
%
|
|
182
|
-
br i1 %
|
|
182
|
+
define private void @eraseObject(%Object %object) alwaysinline {
|
|
183
|
+
%isNull = icmp eq %Object %object, null
|
|
184
|
+
br i1 %isNull, label %done, label %next
|
|
183
185
|
|
|
184
186
|
next:
|
|
185
|
-
%
|
|
186
|
-
%
|
|
187
|
-
switch %
|
|
187
|
+
%objectReferenceCount = getelementptr %Header, ptr %object, i64 0, i32 0
|
|
188
|
+
%referenceCount = load %ReferenceCount, ptr %objectReferenceCount
|
|
189
|
+
switch %ReferenceCount %referenceCount, label %decr [%ReferenceCount 0, label %free]
|
|
188
190
|
|
|
189
191
|
decr:
|
|
190
|
-
%
|
|
191
|
-
store %
|
|
192
|
+
%referenceCount.1 = sub %ReferenceCount %referenceCount, 1
|
|
193
|
+
store %ReferenceCount %referenceCount.1, ptr %objectReferenceCount
|
|
192
194
|
ret void
|
|
193
195
|
|
|
194
196
|
free:
|
|
195
|
-
%
|
|
196
|
-
%eraser = load %Eraser, ptr %
|
|
197
|
-
%
|
|
198
|
-
call
|
|
199
|
-
call void @free(%
|
|
197
|
+
%objectEraser = getelementptr %Header, ptr %object, i64 0, i32 1
|
|
198
|
+
%eraser = load %Eraser, ptr %objectEraser
|
|
199
|
+
%environment = call %Environment @objectEnvironment(%Object %object)
|
|
200
|
+
call void %eraser(%Environment %environment)
|
|
201
|
+
call void @free(%Object %object)
|
|
200
202
|
br label %done
|
|
201
203
|
|
|
202
204
|
done:
|
|
@@ -204,416 +206,575 @@ define void @eraseObject(%Obj %obj) alwaysinline {
|
|
|
204
206
|
}
|
|
205
207
|
|
|
206
208
|
define void @erasePositive(%Pos %val) alwaysinline {
|
|
207
|
-
%
|
|
208
|
-
tail call void @eraseObject(%
|
|
209
|
+
%object = extractvalue %Pos %val, 1
|
|
210
|
+
tail call void @eraseObject(%Object %object)
|
|
209
211
|
ret void
|
|
210
212
|
}
|
|
211
213
|
|
|
212
214
|
define void @eraseNegative(%Neg %val) alwaysinline {
|
|
213
|
-
%
|
|
214
|
-
tail call void @eraseObject(%
|
|
215
|
+
%object = extractvalue %Neg %val, 1
|
|
216
|
+
tail call void @eraseObject(%Object %object)
|
|
215
217
|
ret void
|
|
216
218
|
}
|
|
217
219
|
|
|
218
220
|
|
|
219
221
|
; Arena management
|
|
220
|
-
define ptr @getRegionPointer(
|
|
222
|
+
define private ptr @getRegionPointer(%Prompt %prompt, %Stack %stack) {
|
|
221
223
|
entry:
|
|
222
|
-
|
|
224
|
+
%prompt_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 3
|
|
225
|
+
%currentPrompt = load %Prompt, ptr %prompt_pointer
|
|
226
|
+
%promptMatch = icmp eq %Prompt %currentPrompt, %prompt
|
|
227
|
+
br i1 %promptMatch, label %found, label %continue
|
|
223
228
|
|
|
224
|
-
|
|
225
|
-
|
|
229
|
+
continue:
|
|
230
|
+
%nextStack_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 4
|
|
231
|
+
%nextStack = load %Stack, ptr %nextStack_pointer
|
|
232
|
+
%region = tail call ptr @getRegionPointer(%Prompt %prompt, %Stack %nextStack)
|
|
233
|
+
ret ptr %region
|
|
234
|
+
|
|
235
|
+
found:
|
|
236
|
+
%stackRegion = getelementptr %StackValue, %Stack %stack, i64 0, i32 2
|
|
237
|
+
ret ptr %stackRegion
|
|
238
|
+
}
|
|
226
239
|
|
|
227
|
-
|
|
228
|
-
%
|
|
229
|
-
%i = phi i64 [%evidence, %entry], [%nexti, %loop]
|
|
230
|
-
%stk = load %Stk, ptr %stkp
|
|
231
|
-
%regionp = getelementptr %StkVal, %Stk %stk, i64 0, i32 2
|
|
232
|
-
%nextp = getelementptr %StkVal, %Stk %stk, i64 0, i32 3
|
|
233
|
-
%nexti = sub i64 %i, 1
|
|
234
|
-
%cmp = icmp eq i64 %nexti, 0
|
|
240
|
+
define private { ptr, %Reference } @alloc(i64 %index, %Prompt %prompt, %Stack %stack) alwaysinline {
|
|
241
|
+
%region_pointer = call ptr @getRegionPointer(%Prompt %prompt, %Stack %stack)
|
|
235
242
|
|
|
236
|
-
|
|
243
|
+
%stackPointer_pointer = getelementptr %Region, ptr %region_pointer, i64 0, i64 %index, i32 0
|
|
244
|
+
%base_pointer = getelementptr %Region, ptr %region_pointer, i64 0, i64 %index, i32 1
|
|
245
|
+
%limit_pointer = getelementptr %Region, ptr %region_pointer, i64 0, i64 %index, i32 2
|
|
237
246
|
|
|
238
|
-
|
|
239
|
-
|
|
247
|
+
%stackPointer = load %StackPointer, ptr %stackPointer_pointer
|
|
248
|
+
%base = load %Base, ptr %base_pointer
|
|
249
|
+
%limit = load %Limit, ptr %limit_pointer
|
|
240
250
|
|
|
251
|
+
%object = icmp ne i64 %index, 0
|
|
252
|
+
%size = select i1 %object, i64 16, i64 8
|
|
253
|
+
|
|
254
|
+
%nextStackPointer = getelementptr i8, %StackPointer %stackPointer, i64 %size
|
|
255
|
+
|
|
256
|
+
%cmp = icmp ule %StackPointer %nextStackPointer, %limit
|
|
257
|
+
br i1 %cmp, label %continue, label %realloc
|
|
258
|
+
|
|
259
|
+
continue:
|
|
260
|
+
store %StackPointer %nextStackPointer, ptr %stackPointer_pointer
|
|
261
|
+
%intBase = ptrtoint %Base %base to i64
|
|
262
|
+
%intStackPointer = ptrtoint %StackPointer %stackPointer to i64
|
|
263
|
+
%offset64 = sub i64 %intStackPointer, %intBase
|
|
264
|
+
|
|
265
|
+
%prompt32 = trunc i64 %prompt to i32
|
|
266
|
+
%offset32 = trunc i64 %offset64 to i32
|
|
267
|
+
|
|
268
|
+
%ret.0 = insertvalue { ptr, %Reference } undef, %StackPointer %stackPointer, 0
|
|
269
|
+
%ref.1 = insertvalue %Reference undef, i32 %prompt32, 0
|
|
270
|
+
%ref.2 = insertvalue %Reference %ref.1, i32 %offset32, 1
|
|
271
|
+
%ret.1 = insertvalue { ptr, %Reference } %ret.0, %Reference %ref.2, 1
|
|
272
|
+
ret { ptr, %Reference } %ret.1
|
|
273
|
+
|
|
274
|
+
realloc:
|
|
275
|
+
%intBase_2 = ptrtoint %Base %base to i64
|
|
276
|
+
%intLimit = ptrtoint %Limit %limit to i64
|
|
277
|
+
%arenaSize = sub i64 %intLimit, %intBase_2
|
|
278
|
+
%empty = icmp eq i64 %arenaSize, 0
|
|
279
|
+
%double = mul i64 %arenaSize, 2
|
|
280
|
+
%newArenaSize = select i1 %empty, i64 1024, i64 %double
|
|
281
|
+
|
|
282
|
+
%newBase = call ptr @realloc(ptr %base, i64 %newArenaSize)
|
|
283
|
+
%newlimit = getelementptr i8, %Base %newBase, i64 %newArenaSize
|
|
284
|
+
%newStackPointer = getelementptr i8, %Base %newBase, i64 %arenaSize
|
|
285
|
+
%newNextStackPointer = getelementptr i8, %StackPointer %newStackPointer, i64 %size
|
|
286
|
+
|
|
287
|
+
store %Base %newBase, ptr %base_pointer
|
|
288
|
+
store %Limit %newlimit, ptr %limit_pointer
|
|
289
|
+
store %StackPointer %newNextStackPointer, ptr %stackPointer_pointer
|
|
290
|
+
|
|
291
|
+
%prompt32_2 = trunc i64 %prompt to i32
|
|
292
|
+
%arenaSize32 = trunc i64 %arenaSize to i32
|
|
293
|
+
|
|
294
|
+
%ret..0 = insertvalue { ptr, %Reference } undef, %StackPointer %newStackPointer, 0
|
|
295
|
+
%ref..1 = insertvalue %Reference undef, i32 %prompt32_2, 0
|
|
296
|
+
%ref..2 = insertvalue %Reference %ref..1, i32 %arenaSize32, 1
|
|
297
|
+
%ret..1 = insertvalue { ptr, %Reference } %ret..0, %Reference %ref..2, 1
|
|
298
|
+
ret { ptr, %Reference } %ret..1
|
|
241
299
|
}
|
|
242
300
|
|
|
243
301
|
|
|
302
|
+
define private ptr @getPointer(%Reference %reference, i64 %index, %Stack %stack) {
|
|
303
|
+
%prompt32 = extractvalue %Reference %reference, 0
|
|
304
|
+
%offset32 = extractvalue %Reference %reference, 1
|
|
305
|
+
%prompt = zext i32 %prompt32 to i64
|
|
306
|
+
%offset = zext i32 %offset32 to i64
|
|
244
307
|
|
|
245
|
-
|
|
246
|
-
%
|
|
247
|
-
%
|
|
248
|
-
%
|
|
249
|
-
|
|
308
|
+
%region_pointer = call ptr @getRegionPointer(%Prompt %prompt, %Stack %stack)
|
|
309
|
+
%base_pointer = getelementptr %Region, ptr %region_pointer, i64 0, i64 %index, i32 1
|
|
310
|
+
%base = load %Base, ptr %base_pointer
|
|
311
|
+
%pointer = getelementptr i8, ptr %base, i64 %offset
|
|
312
|
+
ret ptr %pointer
|
|
313
|
+
}
|
|
250
314
|
|
|
251
|
-
|
|
252
|
-
%
|
|
253
|
-
%
|
|
315
|
+
define private %Stack @getStack(%Stack %stack, %Prompt %prompt) {
|
|
316
|
+
%promptPointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 3
|
|
317
|
+
%thisPrompt = load %Prompt, ptr %promptPointer
|
|
318
|
+
%found = icmp eq %Prompt %prompt, %thisPrompt
|
|
319
|
+
br i1 %found, label %done, label %recurse
|
|
254
320
|
|
|
255
|
-
|
|
256
|
-
%
|
|
321
|
+
done:
|
|
322
|
+
ret %Stack %stack
|
|
257
323
|
|
|
258
|
-
|
|
324
|
+
recurse:
|
|
325
|
+
%nextStackPointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 4
|
|
326
|
+
%nextStack = load %Stack, ptr %nextStackPointer
|
|
327
|
+
%result = call %Stack @getStack(%Stack %nextStack, %Prompt %prompt)
|
|
328
|
+
ret %Stack %result
|
|
329
|
+
}
|
|
259
330
|
|
|
260
|
-
|
|
261
|
-
|
|
331
|
+
define private ptr @getVarPointer(%Reference %reference, %Stack %stack) {
|
|
332
|
+
%prompt32 = extractvalue %Reference %reference, 0
|
|
333
|
+
%offset32 = extractvalue %Reference %reference, 1
|
|
334
|
+
%prompt = zext i32 %prompt32 to i64
|
|
335
|
+
%offset = zext i32 %offset32 to i64
|
|
336
|
+
|
|
337
|
+
%targetStack = call %Stack @getStack(%Stack %stack, %Prompt %prompt)
|
|
338
|
+
%basePointer = getelementptr %StackValue, %Stack %targetStack, i64 0, i32 1, i32 1
|
|
339
|
+
%base = load %Base, ptr %basePointer
|
|
340
|
+
%varPointer = getelementptr i8, %Base %base, i64 %offset
|
|
341
|
+
ret ptr %varPointer
|
|
342
|
+
}
|
|
262
343
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
%
|
|
266
|
-
%intsp = ptrtoint %Sp %sp to i64
|
|
267
|
-
%offset = sub i64 %intsp, %intb
|
|
344
|
+
define private %Reference @newReference(%Stack %stack) alwaysinline {
|
|
345
|
+
%stackPointerPointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 1, i32 0
|
|
346
|
+
%basePointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 1, i32 1
|
|
268
347
|
|
|
269
|
-
%
|
|
270
|
-
%
|
|
271
|
-
ret { ptr, %Ref } %ret.1
|
|
348
|
+
%stackPointer = load %StackPointer, ptr %stackPointerPointer
|
|
349
|
+
%base = load %StackPointer, ptr %basePointer
|
|
272
350
|
|
|
273
|
-
|
|
274
|
-
%
|
|
275
|
-
%intlimit = ptrtoint %Limit %limit to i64
|
|
276
|
-
%arenasize = sub i64 %intlimit, %intbase
|
|
277
|
-
%empty = icmp eq i64 %arenasize, 0
|
|
278
|
-
%double = mul i64 %arenasize, 2
|
|
279
|
-
%newarenasize = select i1 %empty, i64 1024, i64 %double
|
|
351
|
+
%intStack = ptrtoint %StackPointer %stackPointer to i64
|
|
352
|
+
%intBase = ptrtoint %StackPointer %base to i64
|
|
280
353
|
|
|
281
|
-
%
|
|
282
|
-
%
|
|
283
|
-
%newsp = getelementptr i8, %Base %newbase, i64 %arenasize
|
|
284
|
-
%newnextsp = getelementptr i8, %Sp %newsp, i64 %size
|
|
354
|
+
%offset = sub i64 %intStack, %intBase
|
|
355
|
+
%offset32 = trunc i64 %offset to i32
|
|
285
356
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
store %Sp %newnextsp, ptr %spp
|
|
357
|
+
%prompt = call %Prompt @currentPrompt(%Stack %stack)
|
|
358
|
+
%prompt32 = trunc %Prompt %prompt to i32
|
|
289
359
|
|
|
290
|
-
%
|
|
291
|
-
%
|
|
292
|
-
ret { ptr, %Ref } %ret..1
|
|
360
|
+
%reference..1 = insertvalue %Reference undef, i32 %prompt32, 0
|
|
361
|
+
%reference = insertvalue %Reference %reference..1, i32 %offset32, 1
|
|
293
362
|
|
|
363
|
+
ret %Reference %reference
|
|
294
364
|
}
|
|
295
365
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
%
|
|
300
|
-
%
|
|
301
|
-
|
|
366
|
+
; Stack management
|
|
367
|
+
|
|
368
|
+
define private %StackPointer @stackAllocate(%Stack %stack, i64 %n) {
|
|
369
|
+
%stackStackPointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 1, i32 0
|
|
370
|
+
%stackPointer = load %StackPointer, ptr %stackStackPointer
|
|
371
|
+
|
|
372
|
+
%stackPointer_2 = getelementptr i8, %StackPointer %stackPointer, i64 %n
|
|
373
|
+
store %StackPointer %stackPointer_2, ptr %stackStackPointer
|
|
374
|
+
ret %StackPointer %stackPointer
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
define private %StackPointer @stackDeallocate(%Stack %stack, i64 %n) {
|
|
378
|
+
%stackStackPointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 1, i32 0
|
|
379
|
+
%stackPointer = load %StackPointer, ptr %stackStackPointer
|
|
380
|
+
|
|
381
|
+
%o = sub i64 0, %n
|
|
382
|
+
%stackPointer_2 = getelementptr i8, %StackPointer %stackPointer, i64 %o
|
|
383
|
+
store %StackPointer %stackPointer_2, ptr %stackStackPointer
|
|
384
|
+
|
|
385
|
+
ret %StackPointer %stackPointer_2
|
|
302
386
|
}
|
|
303
387
|
|
|
304
388
|
; Meta-stack management
|
|
305
389
|
|
|
306
|
-
define %
|
|
307
|
-
%
|
|
308
|
-
%limit = getelementptr i8, ptr %
|
|
390
|
+
define private %Memory @newMemory() {
|
|
391
|
+
%stackPointer = call %StackPointer @malloc(i64 268435456)
|
|
392
|
+
%limit = getelementptr i8, ptr %stackPointer, i64 268435456
|
|
309
393
|
|
|
310
|
-
%
|
|
311
|
-
%
|
|
312
|
-
%
|
|
394
|
+
%memory.0 = insertvalue %Memory undef, %StackPointer %stackPointer, 0
|
|
395
|
+
%memory.1 = insertvalue %Memory %memory.0, %Base %stackPointer, 1
|
|
396
|
+
%memory.2 = insertvalue %Memory %memory.1, %Limit %limit, 2
|
|
313
397
|
|
|
314
|
-
ret %
|
|
398
|
+
ret %Memory %memory.2
|
|
315
399
|
}
|
|
316
400
|
|
|
317
|
-
define %
|
|
401
|
+
define private %Stack @newStack(%Prompt %prompt) {
|
|
318
402
|
|
|
319
403
|
; TODO find actual size of stack
|
|
320
|
-
%
|
|
404
|
+
%stack = call ptr @malloc(i64 120)
|
|
321
405
|
|
|
322
406
|
; TODO initialize to zero and grow later
|
|
323
|
-
%
|
|
407
|
+
%stackMemory = call %Memory @newMemory()
|
|
324
408
|
|
|
325
|
-
%
|
|
326
|
-
%
|
|
327
|
-
%
|
|
328
|
-
%
|
|
409
|
+
%stack.0 = insertvalue %StackValue undef, %ReferenceCount 0, 0
|
|
410
|
+
%stack.1 = insertvalue %StackValue %stack.0, %Memory %stackMemory, 1
|
|
411
|
+
%stack.2 = insertvalue %StackValue %stack.1, %Region zeroinitializer, 2
|
|
412
|
+
%stack.3 = insertvalue %StackValue %stack.2, %Prompt %prompt, 3
|
|
413
|
+
%stack.4 = insertvalue %StackValue %stack.3, %Stack zeroinitializer, 4
|
|
329
414
|
|
|
330
|
-
store %
|
|
415
|
+
store %StackValue %stack.4, %Stack %stack
|
|
331
416
|
|
|
332
|
-
ret %
|
|
417
|
+
ret %Stack %stack
|
|
333
418
|
}
|
|
334
419
|
|
|
335
|
-
define
|
|
336
|
-
%
|
|
420
|
+
define private void @pushStack(%Stack %stack, %Stack %oldStack) {
|
|
421
|
+
%stackRest = getelementptr %StackValue, %Stack %stack, i64 0, i32 4
|
|
422
|
+
%rest = load %Stack, ptr %stackRest
|
|
423
|
+
%isNull = icmp eq %Stack %rest, null
|
|
424
|
+
br i1 %isNull, label %done, label %next
|
|
337
425
|
|
|
338
|
-
|
|
426
|
+
done:
|
|
427
|
+
store %Stack %oldStack, ptr %stackRest
|
|
428
|
+
ret void
|
|
339
429
|
|
|
340
|
-
|
|
430
|
+
next:
|
|
431
|
+
tail call void @pushStack(%Stack %rest, %Stack %oldStack)
|
|
432
|
+
ret void
|
|
433
|
+
}
|
|
341
434
|
|
|
342
|
-
|
|
435
|
+
define private %Stack @popStacks(%Stack %stack, %Prompt %prompt) {
|
|
436
|
+
entry:
|
|
437
|
+
%prompt_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 3
|
|
438
|
+
%currentPrompt = load %Prompt, ptr %prompt_pointer
|
|
439
|
+
%promptMatch = icmp eq %Prompt %currentPrompt, %prompt
|
|
440
|
+
br i1 %promptMatch, label %found, label %continue
|
|
343
441
|
|
|
344
|
-
|
|
345
|
-
|
|
442
|
+
continue:
|
|
443
|
+
%nextStack_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 4
|
|
444
|
+
%nextStack = load %Stack, ptr %nextStack_pointer
|
|
445
|
+
%result = tail call %Stack @popStacks(%Stack %nextStack, %Prompt %prompt)
|
|
446
|
+
ret %Stack %result
|
|
447
|
+
|
|
448
|
+
found:
|
|
449
|
+
%nextStack2_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 4
|
|
450
|
+
%nextStack2 = load %Stack, ptr %nextStack2_pointer
|
|
451
|
+
store %Stack null, ptr %nextStack2_pointer
|
|
452
|
+
ret %Stack %nextStack2
|
|
346
453
|
}
|
|
347
454
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
455
|
+
define private void @eraseMemory(%Memory %memory) {
|
|
456
|
+
%stackPointer = extractvalue %Memory %memory, 0
|
|
457
|
+
call void @free(%StackPointer %stackPointer)
|
|
458
|
+
ret void
|
|
459
|
+
}
|
|
353
460
|
|
|
354
|
-
|
|
355
|
-
%
|
|
356
|
-
|
|
461
|
+
define private void @forEachObject(ptr %elementPointer, ptr %end, ptr %f) alwaysinline {
|
|
462
|
+
%done = icmp uge ptr %elementPointer, %end
|
|
463
|
+
br i1 %done, label %return, label %erase
|
|
357
464
|
|
|
358
|
-
|
|
359
|
-
%
|
|
465
|
+
erase:
|
|
466
|
+
%element = load %Pos, ptr %elementPointer
|
|
467
|
+
call void %f(%Pos %element)
|
|
360
468
|
|
|
361
|
-
%
|
|
469
|
+
%nextElementPointer = getelementptr %Pos, ptr %elementPointer, i64 1
|
|
470
|
+
tail call void @forEachObject(ptr %nextElementPointer, ptr %end, ptr %f)
|
|
471
|
+
ret void
|
|
362
472
|
|
|
363
|
-
|
|
364
|
-
|
|
473
|
+
return:
|
|
474
|
+
ret void
|
|
475
|
+
}
|
|
365
476
|
|
|
366
|
-
|
|
367
|
-
|
|
477
|
+
define private void @eraseRegion(%Region %region) alwaysinline {
|
|
478
|
+
%valuesBase = extractvalue %Region %region, 0, 1
|
|
479
|
+
call void @free(%Base %valuesBase)
|
|
368
480
|
|
|
369
|
-
|
|
481
|
+
%objectsBase = extractvalue %Region %region, 1, 1
|
|
482
|
+
%objectsStackPointer = extractvalue %Region %region, 1, 0
|
|
483
|
+
call void @forEachObject(%Base %objectsBase, %StackPointer %objectsStackPointer, %Eraser @erasePositive)
|
|
484
|
+
call void @free(%Base %objectsBase)
|
|
370
485
|
|
|
371
|
-
%
|
|
372
|
-
%
|
|
373
|
-
|
|
486
|
+
%stringsBase = extractvalue %Region %region, 2, 1
|
|
487
|
+
%stringsStackPointer = extractvalue %Region %region, 2, 0
|
|
488
|
+
call void @forEachObject(%Base %stringsBase, %StackPointer %stringsStackPointer, %Eraser @erasePositive)
|
|
489
|
+
call void @free(%Base %stringsBase)
|
|
374
490
|
|
|
375
|
-
ret
|
|
491
|
+
ret void
|
|
376
492
|
}
|
|
377
493
|
|
|
378
|
-
define %
|
|
379
|
-
%
|
|
380
|
-
%
|
|
494
|
+
define private %Stack @underflowStack(%Stack %stack) {
|
|
495
|
+
%stackMemory = getelementptr %StackValue, %Stack %stack, i64 0, i32 1
|
|
496
|
+
%stackRegion = getelementptr %StackValue, %Stack %stack, i64 0, i32 2
|
|
497
|
+
%stackRest = getelementptr %StackValue, %Stack %stack, i64 0, i32 4
|
|
381
498
|
|
|
382
|
-
%
|
|
383
|
-
|
|
499
|
+
%memory = load %Memory, ptr %stackMemory
|
|
500
|
+
%region = load %Region, ptr %stackRegion
|
|
501
|
+
%rest = load %Stack, ptr %stackRest
|
|
384
502
|
|
|
385
|
-
call void @
|
|
386
|
-
|
|
387
|
-
call void @free(%
|
|
388
|
-
call void @free(%Stk %stk)
|
|
503
|
+
call void @eraseMemory(%Memory %memory)
|
|
504
|
+
call void @eraseRegion(%Region %region)
|
|
505
|
+
call void @free(%Stack %stack)
|
|
389
506
|
|
|
390
|
-
|
|
391
|
-
ret %Sp %newsp
|
|
507
|
+
ret %Stack %rest
|
|
392
508
|
}
|
|
393
509
|
|
|
394
|
-
define %
|
|
395
|
-
%
|
|
396
|
-
%base = extractvalue %
|
|
397
|
-
%limit = extractvalue %
|
|
510
|
+
define private %Memory @copyMemory(%Memory %memory) alwaysinline {
|
|
511
|
+
%stackPointer = extractvalue %Memory %memory, 0
|
|
512
|
+
%base = extractvalue %Memory %memory, 1
|
|
513
|
+
%limit = extractvalue %Memory %memory, 2
|
|
398
514
|
|
|
399
|
-
%
|
|
400
|
-
%
|
|
401
|
-
%
|
|
402
|
-
%used = sub i64 %
|
|
403
|
-
%size = sub i64 %
|
|
515
|
+
%intStackPointer = ptrtoint %StackPointer %stackPointer to i64
|
|
516
|
+
%intBase = ptrtoint %Base %base to i64
|
|
517
|
+
%intLimit = ptrtoint %Limit %limit to i64
|
|
518
|
+
%used = sub i64 %intStackPointer, %intBase
|
|
519
|
+
%size = sub i64 %intLimit, %intBase
|
|
404
520
|
|
|
405
|
-
%
|
|
406
|
-
%
|
|
407
|
-
%
|
|
408
|
-
%
|
|
409
|
-
%
|
|
410
|
-
%
|
|
521
|
+
%newBase = call ptr @malloc(i64 %size)
|
|
522
|
+
%intNewBase = ptrtoint %Base %newBase to i64
|
|
523
|
+
%intNewStackPointer = add i64 %intNewBase, %used
|
|
524
|
+
%intNewLimit = add i64 %intNewBase, %size
|
|
525
|
+
%newStackPointer = inttoptr i64 %intNewStackPointer to %StackPointer
|
|
526
|
+
%newLimit = inttoptr i64 %intNewLimit to %Limit
|
|
411
527
|
|
|
412
|
-
call void @memcpy(ptr %
|
|
528
|
+
call void @memcpy(ptr %newBase, ptr %base, i64 %used)
|
|
413
529
|
|
|
414
|
-
%
|
|
415
|
-
%
|
|
416
|
-
%
|
|
530
|
+
%memory.0 = insertvalue %Memory undef, %StackPointer %newStackPointer, 0
|
|
531
|
+
%memory.1 = insertvalue %Memory %memory.0, %Base %newBase, 1
|
|
532
|
+
%memory.2 = insertvalue %Memory %memory.1, %Limit %newLimit, 2
|
|
417
533
|
|
|
418
|
-
ret %
|
|
534
|
+
ret %Memory %memory.2
|
|
419
535
|
}
|
|
420
536
|
|
|
421
|
-
define %Region @copyRegion(%Region %region) alwaysinline {
|
|
422
|
-
%
|
|
423
|
-
%
|
|
424
|
-
%
|
|
537
|
+
define private %Region @copyRegion(%Region %region) alwaysinline {
|
|
538
|
+
%memory.0 = extractvalue %Region %region, 0
|
|
539
|
+
%memory.1 = extractvalue %Region %region, 1
|
|
540
|
+
%memory.2 = extractvalue %Region %region, 2
|
|
425
541
|
|
|
426
|
-
%
|
|
427
|
-
%
|
|
428
|
-
call void @forEachObject(%Base %
|
|
542
|
+
%objectsBase = extractvalue %Region %region, 1, 1
|
|
543
|
+
%objectsStackPointer = extractvalue %Region %region, 1, 0
|
|
544
|
+
call void @forEachObject(%Base %objectsBase, %StackPointer %objectsStackPointer, %Sharer @sharePositive)
|
|
429
545
|
|
|
430
|
-
%
|
|
431
|
-
%
|
|
432
|
-
call void @forEachObject(%Base %
|
|
546
|
+
%stringsBase = extractvalue %Region %region, 2, 1
|
|
547
|
+
%stringsStackPointer = extractvalue %Region %region, 2, 0
|
|
548
|
+
call void @forEachObject(%Base %stringsBase, %StackPointer %stringsStackPointer, %Sharer @sharePositive)
|
|
433
549
|
|
|
434
|
-
%
|
|
435
|
-
%
|
|
436
|
-
%
|
|
550
|
+
%newMemory.0 = call %Memory @copyMemory(%Memory %memory.0)
|
|
551
|
+
%newMemory.1 = call %Memory @copyMemory(%Memory %memory.1)
|
|
552
|
+
%newMemory.2 = call %Memory @copyMemory(%Memory %memory.2)
|
|
437
553
|
|
|
438
|
-
%region.0 = insertvalue %Region undef, %
|
|
439
|
-
%region.1 = insertvalue %Region %region.0, %
|
|
440
|
-
%region.2 = insertvalue %Region %region.1, %
|
|
554
|
+
%region.0 = insertvalue %Region undef, %Memory %newMemory.0, 0
|
|
555
|
+
%region.1 = insertvalue %Region %region.0, %Memory %newMemory.1, 1
|
|
556
|
+
%region.2 = insertvalue %Region %region.1, %Memory %newMemory.2, 2
|
|
441
557
|
|
|
442
558
|
ret %Region %region.2
|
|
443
559
|
}
|
|
444
560
|
|
|
445
|
-
define %
|
|
561
|
+
define private %Stack @uniqueStack(%Stack %stack) alwaysinline {
|
|
446
562
|
|
|
447
563
|
entry:
|
|
448
|
-
%
|
|
449
|
-
%
|
|
450
|
-
switch %
|
|
564
|
+
%stackReferenceCount = getelementptr %StackValue, %Stack %stack, i64 0, i32 0
|
|
565
|
+
%referenceCount = load %ReferenceCount, ptr %stackReferenceCount
|
|
566
|
+
switch %ReferenceCount %referenceCount, label %copy [%ReferenceCount 0, label %done]
|
|
451
567
|
|
|
452
568
|
done:
|
|
453
|
-
ret %
|
|
569
|
+
ret %Stack %stack
|
|
454
570
|
|
|
455
571
|
copy:
|
|
456
|
-
%
|
|
457
|
-
store %
|
|
572
|
+
%newOldReferenceCount = sub %ReferenceCount %referenceCount, 1
|
|
573
|
+
store %ReferenceCount %newOldReferenceCount, ptr %stackReferenceCount
|
|
458
574
|
|
|
459
|
-
%
|
|
575
|
+
%newHead = call ptr @malloc(i64 120)
|
|
460
576
|
br label %loop
|
|
461
577
|
|
|
462
578
|
loop:
|
|
463
|
-
%old = phi %
|
|
464
|
-
%
|
|
579
|
+
%old = phi %Stack [%stack, %copy], [%rest, %next]
|
|
580
|
+
%newStack = phi %Stack [%newHead, %copy], [%nextNew, %next]
|
|
465
581
|
|
|
466
|
-
%
|
|
467
|
-
%
|
|
468
|
-
%
|
|
582
|
+
%stackMemory = getelementptr %StackValue, %Stack %old, i64 0, i32 1
|
|
583
|
+
%stackRegion = getelementptr %StackValue, %Stack %old, i64 0, i32 2
|
|
584
|
+
%stackPrompt = getelementptr %StackValue, %Stack %old, i64 0, i32 3
|
|
585
|
+
%stackRest = getelementptr %StackValue, %Stack %old, i64 0, i32 4
|
|
469
586
|
|
|
470
|
-
%
|
|
471
|
-
%region = load %Region, ptr %
|
|
472
|
-
%
|
|
587
|
+
%memory = load %Memory, ptr %stackMemory
|
|
588
|
+
%region = load %Region, ptr %stackRegion
|
|
589
|
+
%prompt = load %Prompt, ptr %stackPrompt
|
|
590
|
+
%rest = load %Stack, ptr %stackRest
|
|
473
591
|
|
|
474
|
-
%
|
|
475
|
-
%
|
|
476
|
-
%
|
|
477
|
-
%
|
|
592
|
+
%newStackReferenceCount = getelementptr %StackValue, %Stack %newStack, i64 0, i32 0
|
|
593
|
+
%newStackMemory = getelementptr %StackValue, %Stack %newStack, i64 0, i32 1
|
|
594
|
+
%newStackRegion = getelementptr %StackValue, %Stack %newStack, i64 0, i32 2
|
|
595
|
+
%newStackPrompt = getelementptr %StackValue, %Stack %newStack, i64 0, i32 3
|
|
596
|
+
%newStackRest = getelementptr %StackValue, %Stack %newStack, i64 0, i32 4
|
|
478
597
|
|
|
479
|
-
%
|
|
598
|
+
%newMemory = call %Memory @copyMemory(%Memory %memory)
|
|
480
599
|
|
|
481
|
-
%
|
|
482
|
-
call
|
|
600
|
+
%newStackPointer = extractvalue %Memory %newMemory, 0
|
|
601
|
+
call void @shareFrames(%StackPointer %newStackPointer)
|
|
483
602
|
|
|
484
|
-
%
|
|
603
|
+
%newRegion = call %Region @copyRegion(%Region %region)
|
|
485
604
|
|
|
486
|
-
store %
|
|
487
|
-
store %
|
|
488
|
-
store %Region %
|
|
605
|
+
store %ReferenceCount 0, ptr %newStackReferenceCount
|
|
606
|
+
store %Memory %newMemory, ptr %newStackMemory
|
|
607
|
+
store %Region %newRegion, ptr %newStackRegion
|
|
608
|
+
store %Prompt %prompt, ptr %newStackPrompt
|
|
489
609
|
|
|
490
|
-
%
|
|
491
|
-
br i1 %
|
|
610
|
+
%isNull = icmp eq %Stack %rest, null
|
|
611
|
+
br i1 %isNull, label %stop, label %next
|
|
492
612
|
|
|
493
613
|
next:
|
|
494
|
-
%
|
|
495
|
-
store %
|
|
614
|
+
%nextNew = call ptr @malloc(i64 120)
|
|
615
|
+
store %Stack %nextNew, ptr %newStackRest
|
|
496
616
|
br label %loop
|
|
497
617
|
|
|
498
|
-
|
|
499
|
-
store %
|
|
500
|
-
ret %
|
|
501
|
-
|
|
618
|
+
stop:
|
|
619
|
+
store %Stack null, ptr %newStackRest
|
|
620
|
+
ret %Stack %newHead
|
|
502
621
|
}
|
|
503
622
|
|
|
504
|
-
define void @shareStack(%
|
|
505
|
-
%
|
|
506
|
-
%
|
|
507
|
-
%
|
|
508
|
-
store %
|
|
623
|
+
define void @shareStack(%Stack %stack) alwaysinline {
|
|
624
|
+
%stackReferenceCount = getelementptr %StackValue, %Stack %stack, i64 0, i32 0
|
|
625
|
+
%referenceCount = load %ReferenceCount, ptr %stackReferenceCount
|
|
626
|
+
%referenceCount.1 = add %ReferenceCount %referenceCount, 1
|
|
627
|
+
store %ReferenceCount %referenceCount.1, ptr %stackReferenceCount
|
|
509
628
|
ret void
|
|
510
629
|
}
|
|
511
630
|
|
|
512
|
-
define void @eraseStack(%
|
|
513
|
-
%
|
|
514
|
-
%
|
|
515
|
-
switch %
|
|
631
|
+
define void @eraseStack(%Stack %stack) alwaysinline {
|
|
632
|
+
%stackReferenceCount = getelementptr %StackValue, %Stack %stack, i64 0, i32 0
|
|
633
|
+
%referenceCount = load %ReferenceCount, ptr %stackReferenceCount
|
|
634
|
+
switch %ReferenceCount %referenceCount, label %decr [%ReferenceCount 0, label %free]
|
|
516
635
|
|
|
517
636
|
decr:
|
|
518
|
-
%
|
|
519
|
-
store %
|
|
637
|
+
%referenceCount.1 = sub %ReferenceCount %referenceCount, 1
|
|
638
|
+
store %ReferenceCount %referenceCount.1, ptr %stackReferenceCount
|
|
520
639
|
ret void
|
|
521
640
|
|
|
522
641
|
free:
|
|
523
|
-
%
|
|
524
|
-
%
|
|
525
|
-
|
|
642
|
+
%stackStackPointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 1, i32 0
|
|
643
|
+
%stackRegion = getelementptr %StackValue, %Stack %stack, i64 0, i32 2
|
|
644
|
+
%stackRest = getelementptr %StackValue, %Stack %stack, i64 0, i32 4
|
|
526
645
|
|
|
527
|
-
%
|
|
528
|
-
%region = load %Region, ptr %
|
|
646
|
+
%stackPointer = load %StackPointer, ptr %stackStackPointer
|
|
647
|
+
%region = load %Region, ptr %stackRegion
|
|
648
|
+
%rest = load %Stack, ptr %stackRest
|
|
529
649
|
|
|
650
|
+
call void @free(%Stack %stack)
|
|
651
|
+
call void @eraseFrames(%StackPointer %stackPointer)
|
|
530
652
|
call void @eraseRegion(%Region %region)
|
|
531
653
|
|
|
532
|
-
|
|
654
|
+
%isNull = icmp eq %Stack %rest, null
|
|
655
|
+
br i1 %isNull, label %done, label %next
|
|
656
|
+
|
|
657
|
+
next:
|
|
658
|
+
call void @eraseStack(%Stack %rest)
|
|
533
659
|
ret void
|
|
534
|
-
}
|
|
535
660
|
|
|
536
|
-
|
|
537
|
-
%newsp = getelementptr %FrameHeader, %Sp %sp, i64 -1
|
|
538
|
-
%stksharer = getelementptr %FrameHeader, %Sp %newsp, i64 0, i32 1
|
|
539
|
-
%sharer = load %Sharer, ptr %stksharer
|
|
540
|
-
tail call fastcc void %sharer(%Sp %newsp)
|
|
661
|
+
done:
|
|
541
662
|
ret void
|
|
542
663
|
}
|
|
543
664
|
|
|
544
|
-
define
|
|
545
|
-
%
|
|
546
|
-
%
|
|
547
|
-
%
|
|
548
|
-
tail call
|
|
665
|
+
define private void @shareFrames(%StackPointer %stackPointer) alwaysinline {
|
|
666
|
+
%newStackPointer = getelementptr %FrameHeader, %StackPointer %stackPointer, i64 -1
|
|
667
|
+
%stackSharer = getelementptr %FrameHeader, %StackPointer %newStackPointer, i64 0, i32 1
|
|
668
|
+
%sharer = load %Sharer, ptr %stackSharer
|
|
669
|
+
tail call void %sharer(%StackPointer %newStackPointer)
|
|
549
670
|
ret void
|
|
550
671
|
}
|
|
551
672
|
|
|
552
|
-
define void @
|
|
553
|
-
%
|
|
554
|
-
|
|
673
|
+
define private void @eraseFrames(%StackPointer %stackPointer) alwaysinline {
|
|
674
|
+
%newStackPointer = getelementptr %FrameHeader, %StackPointer %stackPointer, i64 -1
|
|
675
|
+
%stackEraser = getelementptr %FrameHeader, %StackPointer %newStackPointer, i64 0, i32 2
|
|
676
|
+
%eraser = load %Eraser, ptr %stackEraser
|
|
677
|
+
tail call void %eraser(%StackPointer %newStackPointer)
|
|
678
|
+
ret void
|
|
679
|
+
}
|
|
555
680
|
|
|
556
|
-
|
|
557
|
-
%element = load %Pos, ptr %elementp
|
|
558
|
-
call void %f(%Pos %element)
|
|
681
|
+
; RTS initialization
|
|
559
682
|
|
|
560
|
-
|
|
561
|
-
|
|
683
|
+
define private tailcc void @topLevel(%Pos %val, %Stack %stack) {
|
|
684
|
+
%rest = call %Stack @underflowStack(%Stack %stack)
|
|
685
|
+
; assert %rest == null
|
|
562
686
|
ret void
|
|
687
|
+
}
|
|
563
688
|
|
|
564
|
-
|
|
689
|
+
define private void @topLevelSharer(%Environment %environment) {
|
|
690
|
+
; TODO this should never be called
|
|
565
691
|
ret void
|
|
566
692
|
}
|
|
567
693
|
|
|
568
|
-
define void @
|
|
569
|
-
|
|
570
|
-
|
|
694
|
+
define private void @topLevelEraser(%Environment %environment) {
|
|
695
|
+
; TODO this should never be called
|
|
696
|
+
ret void
|
|
697
|
+
}
|
|
571
698
|
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
call
|
|
699
|
+
define private %Stack @withEmptyStack() {
|
|
700
|
+
; TODO all stacks share the same source of fresh prompts
|
|
701
|
+
%prompt = call %Prompt @freshPrompt()
|
|
702
|
+
%stack = call %Stack @newStack(%Prompt %prompt)
|
|
576
703
|
|
|
577
|
-
%
|
|
578
|
-
%
|
|
579
|
-
call void @forEachObject(%Base %stringsbase, %Sp %stringssp, %Eraser @c_buffer_refcount_decrement)
|
|
580
|
-
call void @free(%Base %stringsbase)
|
|
704
|
+
%stackStackPointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 1, i32 0
|
|
705
|
+
%stackPointer = load %StackPointer, ptr %stackStackPointer
|
|
581
706
|
|
|
582
|
-
|
|
583
|
-
|
|
707
|
+
%returnAddressPointer = getelementptr %FrameHeader, %StackPointer %stackPointer, i64 0, i32 0
|
|
708
|
+
%sharerPointer = getelementptr %FrameHeader, %StackPointer %stackPointer, i64 0, i32 1
|
|
709
|
+
%eraserPointer = getelementptr %FrameHeader, %StackPointer %stackPointer, i64 0, i32 2
|
|
584
710
|
|
|
585
|
-
|
|
711
|
+
store %ReturnAddress @topLevel, ptr %returnAddressPointer
|
|
712
|
+
store %Sharer @topLevelSharer, ptr %sharerPointer
|
|
713
|
+
store %Eraser @topLevelEraser, ptr %eraserPointer
|
|
586
714
|
|
|
587
|
-
|
|
588
|
-
%
|
|
589
|
-
call void @free(%Base %base)
|
|
715
|
+
%stackPointer_2 = getelementptr %FrameHeader, %StackPointer %stackPointer, i64 1
|
|
716
|
+
store %StackPointer %stackPointer_2, ptr %stackStackPointer
|
|
590
717
|
|
|
591
|
-
%
|
|
592
|
-
|
|
593
|
-
%base.1 = extractvalue %Region %region, 1, 1
|
|
594
|
-
%base.2 = extractvalue %Region %region, 2, 1
|
|
718
|
+
ret %Stack %stack
|
|
719
|
+
}
|
|
595
720
|
|
|
596
|
-
|
|
597
|
-
call
|
|
598
|
-
|
|
721
|
+
define void @resume_Int(%Stack %stack, %Int %argument) {
|
|
722
|
+
%stackPointer = call ccc %StackPointer @stackDeallocate(%Stack %stack, i64 24)
|
|
723
|
+
%returnAddressPointer = getelementptr %FrameHeader, %StackPointer %stackPointer, i64 0, i32 0
|
|
724
|
+
%returnAddress = load %ReturnAddress, ptr %returnAddressPointer
|
|
725
|
+
tail call tailcc void %returnAddress(%Int %argument, %Stack %stack)
|
|
726
|
+
ret void
|
|
727
|
+
}
|
|
599
728
|
|
|
600
|
-
|
|
729
|
+
define void @resume_Pos(%Stack %stack, %Pos %argument) {
|
|
730
|
+
%stackPointer = call ccc %StackPointer @stackDeallocate(%Stack %stack, i64 24)
|
|
731
|
+
%returnAddressPointer = getelementptr %FrameHeader, %StackPointer %stackPointer, i64 0, i32 0
|
|
732
|
+
%returnAddress = load %ReturnAddress, ptr %returnAddressPointer
|
|
733
|
+
tail call tailcc void %returnAddress(%Pos %argument, %Stack %stack)
|
|
601
734
|
ret void
|
|
602
735
|
}
|
|
603
736
|
|
|
604
|
-
define
|
|
605
|
-
;
|
|
737
|
+
define void @run(%Neg %f) {
|
|
738
|
+
; fresh stack
|
|
739
|
+
%stack = call %Stack @withEmptyStack()
|
|
740
|
+
|
|
741
|
+
; prepare call
|
|
742
|
+
%arrayPointer = extractvalue %Neg %f, 0
|
|
743
|
+
%object = extractvalue %Neg %f, 1
|
|
744
|
+
%functionPointerPointer = getelementptr ptr, ptr %arrayPointer, i64 0
|
|
745
|
+
%functionPointer = load ptr, ptr %functionPointerPointer
|
|
746
|
+
|
|
747
|
+
; call
|
|
748
|
+
tail call tailcc %Pos %functionPointer(%Object %object, %Stack %stack)
|
|
606
749
|
ret void
|
|
607
750
|
}
|
|
608
751
|
|
|
609
|
-
define
|
|
610
|
-
;
|
|
752
|
+
define void @run_Int(%Neg %f, i64 %argument) {
|
|
753
|
+
; fresh stack
|
|
754
|
+
%stack = call %Stack @withEmptyStack()
|
|
755
|
+
|
|
756
|
+
; prepare call
|
|
757
|
+
%arrayPointer = extractvalue %Neg %f, 0
|
|
758
|
+
%object = extractvalue %Neg %f, 1
|
|
759
|
+
%functionPointerPointer = getelementptr ptr, ptr %arrayPointer, i64 0
|
|
760
|
+
%functionPointer = load ptr, ptr %functionPointerPointer
|
|
761
|
+
|
|
762
|
+
; call
|
|
763
|
+
tail call tailcc %Pos %functionPointer(%Object %object, %Evidence 0, i64 %argument, %Stack %stack)
|
|
611
764
|
ret void
|
|
612
765
|
}
|
|
613
766
|
|
|
614
|
-
|
|
767
|
+
define void @run_Pos(%Neg %f, %Pos %argument) {
|
|
768
|
+
; fresh stack
|
|
769
|
+
%stack = call %Stack @withEmptyStack()
|
|
615
770
|
|
|
616
|
-
|
|
617
|
-
%
|
|
771
|
+
; prepare call
|
|
772
|
+
%arrayPointer = extractvalue %Neg %f, 0
|
|
773
|
+
%object = extractvalue %Neg %f, 1
|
|
774
|
+
%functionPointerPointer = getelementptr ptr, ptr %arrayPointer, i64 0
|
|
775
|
+
%functionPointer = load ptr, ptr %functionPointerPointer
|
|
618
776
|
|
|
619
|
-
|
|
777
|
+
; call
|
|
778
|
+
tail call tailcc %Pos %functionPointer(%Object %object, %Evidence 0, %Pos %argument, %Stack %stack)
|
|
779
|
+
ret void
|
|
780
|
+
}
|