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