@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.
Files changed (96) hide show
  1. package/bin/effekt +0 -0
  2. package/bin/effekt.sh +1 -1
  3. package/libraries/chez/common/effekt_primitives.ss +10 -2
  4. package/libraries/chez/common/immutable/cslist.effekt +13 -7
  5. package/libraries/chez/common/mutable/dict.effekt +8 -10
  6. package/libraries/chez/common/text/regex.effekt +7 -9
  7. package/libraries/common/args.effekt +95 -0
  8. package/libraries/common/array.effekt +225 -0
  9. package/libraries/common/bench.effekt +60 -0
  10. package/libraries/common/buffer.effekt +123 -0
  11. package/libraries/common/bytes.effekt +125 -0
  12. package/libraries/{chez/common/immutable → common}/dequeue.effekt +18 -4
  13. package/libraries/common/effekt.effekt +764 -0
  14. package/libraries/common/exception.effekt +122 -0
  15. package/libraries/common/io/console.effekt +66 -0
  16. package/libraries/common/io/error.effekt +365 -0
  17. package/libraries/common/io/files.effekt +282 -0
  18. package/libraries/common/io/network.effekt +105 -0
  19. package/libraries/common/io/time.effekt +15 -0
  20. package/libraries/common/io.effekt +158 -0
  21. package/libraries/{llvm/immutable → common}/list.effekt +83 -74
  22. package/libraries/common/option.effekt +72 -0
  23. package/libraries/common/process.effekt +10 -0
  24. package/libraries/common/queue.effekt +140 -0
  25. package/libraries/common/ref.effekt +63 -0
  26. package/libraries/common/result.effekt +45 -0
  27. package/libraries/{ml/immutable → common}/seq.effekt +30 -19
  28. package/libraries/common/string.effekt +395 -0
  29. package/libraries/common/test.effekt +98 -0
  30. package/libraries/js/effekt_builtins.js +37 -6
  31. package/libraries/js/io.js +143 -0
  32. package/libraries/js/mutable/map.effekt +8 -9
  33. package/libraries/js/text/regex.effekt +7 -8
  34. package/libraries/js/unsafe/cont.effekt +2 -2
  35. package/libraries/js/web/dom.effekt +13 -13
  36. package/libraries/llvm/array.c +53 -0
  37. package/libraries/llvm/buffer.c +181 -76
  38. package/libraries/llvm/forward-declare-c.ll +27 -8
  39. package/libraries/llvm/io.c +543 -1
  40. package/libraries/llvm/io.ll +19 -0
  41. package/libraries/llvm/main.c +3 -1
  42. package/libraries/llvm/ref.c +45 -0
  43. package/libraries/llvm/rts.ll +496 -354
  44. package/libraries/llvm/types.c +23 -0
  45. package/libraries/ml/effekt.sml +2 -0
  46. package/libraries/ml/internal/mllist.effekt +9 -0
  47. package/libraries/ml/internal/mloption.effekt +18 -0
  48. package/libraries/ml/random.effekt +9 -9
  49. package/libraries/ml/text/regex.effekt +14 -19
  50. package/licenses/eclipse public license, version 2.0 - epl-2.0.html +2 -2
  51. package/licenses/mit license - mit-license.html +527 -57
  52. package/licenses/the bsd license - bsd-license.html +530 -55
  53. package/licenses/the mit license - mit.html +528 -58
  54. package/package.json +2 -2
  55. package/libraries/chez/callcc/effekt.effekt +0 -221
  56. package/libraries/chez/common/effekt_matching.ss +0 -100
  57. package/libraries/chez/common/immutable/list.effekt +0 -643
  58. package/libraries/chez/common/immutable/option.effekt +0 -39
  59. package/libraries/chez/common/immutable/result.effekt +0 -29
  60. package/libraries/chez/common/io/args.effekt +0 -20
  61. package/libraries/chez/common/mutable/array.effekt +0 -27
  62. package/libraries/chez/common/mutable/heap.effekt +0 -12
  63. package/libraries/chez/common/test.effekt +0 -59
  64. package/libraries/chez/common/text/string.effekt +0 -46
  65. package/libraries/chez/lift/effekt.effekt +0 -217
  66. package/libraries/chez/monadic/effekt.effekt +0 -218
  67. package/libraries/js/effekt.effekt +0 -284
  68. package/libraries/js/effekt_matching.js +0 -79
  69. package/libraries/js/immutable/dequeue.effekt +0 -78
  70. package/libraries/js/immutable/list.effekt +0 -643
  71. package/libraries/js/immutable/option.effekt +0 -49
  72. package/libraries/js/immutable/result.effekt +0 -29
  73. package/libraries/js/io/args.effekt +0 -9
  74. package/libraries/js/io/async.effekt +0 -28
  75. package/libraries/js/io/async.js +0 -2
  76. package/libraries/js/io/file.effekt +0 -50
  77. package/libraries/js/io/file_include.js +0 -13
  78. package/libraries/js/mutable/array.effekt +0 -98
  79. package/libraries/js/mutable/heap.effekt +0 -32
  80. package/libraries/js/test.effekt +0 -59
  81. package/libraries/js/text/string.effekt +0 -64
  82. package/libraries/llvm/effekt.effekt +0 -243
  83. package/libraries/llvm/immutable/option.effekt +0 -53
  84. package/libraries/llvm/immutable/result.effekt +0 -29
  85. package/libraries/llvm/io/args.effekt +0 -24
  86. package/libraries/llvm/text/string.effekt +0 -179
  87. package/libraries/ml/effekt.effekt +0 -267
  88. package/libraries/ml/immutable/dequeue.effekt +0 -81
  89. package/libraries/ml/immutable/list.effekt +0 -674
  90. package/libraries/ml/immutable/option.effekt +0 -53
  91. package/libraries/ml/immutable/result.effekt +0 -29
  92. package/libraries/ml/internal/option.effekt +0 -18
  93. package/libraries/ml/io/args.effekt +0 -41
  94. package/libraries/ml/mutable/array.effekt +0 -43
  95. package/libraries/ml/test.effekt +0 -60
  96. package/libraries/ml/text/string.effekt +0 -81
@@ -1,11 +1,13 @@
1
1
  ; Run-Time System
2
2
 
3
+ %Evidence = type i64
4
+
3
5
  ; Basic types
4
6
 
5
- %Env = type ptr
7
+ %Environment = type ptr
6
8
 
7
9
  ; Reference counts
8
- %Rc = type i64
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 {%Rc, %Eraser}
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
- ; | Rc | Eraser | Payload ... |
23
- ; +--------------+-------------+
24
- %Obj = type ptr
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
- ; | RetAdr | Sharer | Eraser | Payload ... |
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
- ; : : <- Sp
41
+ ; : : <- StackPointer
40
42
  ; +--------------------+
41
43
  ; | FrameHeader |
42
44
  ; | z |
@@ -47,14 +49,14 @@
47
49
  ; +--------------------+
48
50
  ; : ... :
49
51
  ; +--------------------+ <- Base
50
- %Sp = type ptr
51
- %Base = type %Sp
52
- %Limit = type %Sp
53
- %RetAdr = type ptr
54
- %FrameHeader = type { %RetAdr, %Sharer, %Eraser }
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
- %Mem = type { %Sp, %Base, %Limit }
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 %Mem ]
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
- ; The "meta" stack (a stack of stacks)
68
- %Stk = type ptr
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
- %StkVal = type { %Rc, %Mem, %Region, %Stk }
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
- define %StkVal @getStk(%Sp %sp) alwaysinline {
95
- %base = load %Base, ptr @base
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
- %stk.0 = insertvalue %StkVal undef, %Rc 0, 0
101
- %stk.1 = insertvalue %StkVal %stk.0, %Sp %sp, 1, 0
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
- ret %StkVal %stk.5
108
- }
95
+ ; Builtin Types
109
96
 
110
- define void @setStk(%StkVal %stk) alwaysinline {
111
- %base = extractvalue %StkVal %stk, 1, 1
112
- %limit = extractvalue %StkVal %stk, 1, 2
113
- %region = extractvalue %StkVal %stk, 2
114
- %rest = extractvalue %StkVal %stk, 3
115
-
116
- store %Base %base, ptr @base
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 %Obj @newObject(%Eraser %eraser, i64 %envsize) alwaysinline {
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 %envsize, 16
139
- %obj = call ptr @malloc(i64 %size)
140
- %objrc = getelementptr %Header, ptr %obj, i64 0, i32 0
141
- %objeraser = getelementptr %Header, ptr %obj, i64 0, i32 1
142
- store %Rc 0, ptr %objrc
143
- store %Eraser %eraser, ptr %objeraser
144
- ret %Obj %obj
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 %Env @objectEnvironment(%Obj %obj) alwaysinline {
145
+ define %Environment @objectEnvironment(%Object %object) alwaysinline {
148
146
  ; Environment is stored right after header
149
- %env = getelementptr %Header, ptr %obj, i64 1
150
- ret %Env %env
147
+ %environment = getelementptr %Header, ptr %object, i64 1
148
+ ret %Environment %environment
151
149
  }
152
150
 
153
- define void @shareObject(%Obj %obj) alwaysinline {
154
- %isnull = icmp eq %Obj %obj, null
155
- br i1 %isnull, label %done, label %next
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
- %objrc = getelementptr %Header, ptr %obj, i64 0, i32 0
159
- %rc = load %Rc, ptr %objrc
160
- %rc.1 = add %Rc %rc, 1
161
- store %Rc %rc.1, ptr %objrc
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
- %obj = extractvalue %Pos %val, 1
170
- tail call void @shareObject(%Obj %obj)
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
- %obj = extractvalue %Neg %val, 1
176
- tail call void @shareObject(%Obj %obj)
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(%Obj %obj) alwaysinline {
181
- %isnull = icmp eq %Obj %obj, null
182
- br i1 %isnull, label %done, label %next
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
- %objrc = getelementptr %Header, ptr %obj, i64 0, i32 0
186
- %rc = load %Rc, ptr %objrc
187
- switch %Rc %rc, label %decr [%Rc 0, label %free]
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
- %rc.1 = sub %Rc %rc, 1
191
- store %Rc %rc.1, ptr %objrc
188
+ %referenceCount.1 = sub %ReferenceCount %referenceCount, 1
189
+ store %ReferenceCount %referenceCount.1, ptr %objectReferenceCount
192
190
  ret void
193
191
 
194
192
  free:
195
- %objeraser = getelementptr %Header, ptr %obj, i64 0, i32 1
196
- %eraser = load %Eraser, ptr %objeraser
197
- %env = call %Env @objectEnvironment(%Obj %obj)
198
- call fastcc void %eraser(%Env %env)
199
- call void @free(%Obj %obj)
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
- %obj = extractvalue %Pos %val, 1
208
- tail call void @eraseObject(%Obj %obj)
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
- %obj = extractvalue %Neg %val, 1
214
- tail call void @eraseObject(%Obj %obj)
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(i64 %evidence) alwaysinline {
218
+ define ptr @getRegionPointer(%Prompt %prompt, %Stack %stack) {
221
219
  entry:
222
- switch i64 %evidence, label %loop [i64 0, label %here]
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
- here:
225
- ret ptr @region
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
- loop:
228
- %stkp = phi ptr [@rest, %entry], [%nextp, %loop]
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
- br i1 %cmp, label %done, label %loop
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
- done:
239
- ret ptr %regionp
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
- define { ptr, %Ref } @alloc(i64 %idx, i64 %evidence) alwaysinline {
246
- %regionp = call ptr @getRegionPointer(i64 %evidence)
247
- %spp = getelementptr %Region, ptr %regionp, i64 0, i64 %idx, i32 0
248
- %basep = getelementptr %Region, ptr %regionp, i64 0, i64 %idx, i32 1
249
- %limitp = getelementptr %Region, ptr %regionp, i64 0, i64 %idx, i32 2
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
- %sp = load %Sp, ptr %spp
252
- %base = load %Base, ptr %basep
253
- %limit = load %Limit, ptr %limitp
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
- %obj = icmp ne i64 %idx, 0
256
- %size = select i1 %obj, i64 16, i64 8
317
+ done:
318
+ ret %Stack %stack
257
319
 
258
- %nextsp = getelementptr i8, %Sp %sp, i64 %size
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
- %cmp = icmp ule %Sp %nextsp, %limit
261
- br i1 %cmp, label %continue, label %realloc
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
- continue:
264
- store %Sp %nextsp, ptr %spp
265
- %intb = ptrtoint %Base %base to i64
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
- %ret.0 = insertvalue { ptr, %Ref } undef, %Sp %sp, 0
270
- %ret.1 = insertvalue { ptr, %Ref } %ret.0, %Ref %offset, 1
271
- ret { ptr, %Ref } %ret.1
344
+ %stackPointer = load %StackPointer, ptr %stackPointerPointer
345
+ %base = load %StackPointer, ptr %basePointer
272
346
 
273
- realloc:
274
- %intbase = ptrtoint %Base %base to i64
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
- %newbase = call ptr @realloc(ptr %base, i64 %newarenasize)
282
- %newlimit = getelementptr i8, %Base %newbase, i64 %newarenasize
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
- store %Base %newbase, ptr %basep
287
- store %Limit %newlimit, ptr %limitp
288
- store %Sp %newnextsp, ptr %spp
353
+ %prompt = call %Prompt @currentPrompt(%Stack %stack)
354
+ %prompt32 = trunc %Prompt %prompt to i32
289
355
 
290
- %ret..0 = insertvalue { ptr, %Ref } undef, %Sp %newsp, 0
291
- %ret..1 = insertvalue { ptr, %Ref } %ret..0, %Ref %arenasize, 1
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
- define ptr @getPtr(%Ref %ref, i64 %idx, i64 %evidence) alwaysinline {
297
- %regionp = call ptr @getRegionPointer(i64 %evidence)
298
- %basep = getelementptr %Region, ptr %regionp, i64 0, i64 %idx, i32 1
299
- %base = load %Base, ptr %basep
300
- %ptr = getelementptr i8, ptr %base, %Ref %ref
301
- ret ptr %ptr
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 %Mem @newMem() alwaysinline {
307
- %sp = call %Sp @malloc(i64 1024)
308
- %limit = getelementptr i8, ptr %sp, i64 1024
386
+ define %Memory @newMemory() {
387
+ %stackPointer = call %StackPointer @malloc(i64 268435456)
388
+ %limit = getelementptr i8, ptr %stackPointer, i64 268435456
309
389
 
310
- %mem.0 = insertvalue %Mem undef, %Sp %sp, 0
311
- %mem.1 = insertvalue %Mem %mem.0, %Base %sp, 1
312
- %mem.2 = insertvalue %Mem %mem.1, %Limit %limit, 2
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 %Mem %mem.2
394
+ ret %Memory %memory.2
315
395
  }
316
396
 
317
- define %Stk @newStack() alwaysinline {
397
+ define %Stack @newStack(%Prompt %prompt) {
318
398
 
319
399
  ; TODO find actual size of stack
320
- %stk = call ptr @malloc(i64 112)
400
+ %stack = call ptr @malloc(i64 120)
321
401
 
322
402
  ; TODO initialize to zero and grow later
323
- %stackmem = call %Mem @newMem()
403
+ %stackMemory = call %Memory @newMemory()
324
404
 
325
- %stk.0 = insertvalue %StkVal undef, %Rc 0, 0
326
- %stk.1 = insertvalue %StkVal %stk.0, %Mem %stackmem, 1
327
- %stk.2 = insertvalue %StkVal %stk.1, %Region zeroinitializer, 2
328
- %stk.3 = insertvalue %StkVal %stk.2, %Stk %stk, 3
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 %StkVal %stk.3, %Stk %stk
411
+ store %StackValue %stack.4, %Stack %stack
331
412
 
332
- ret %Stk %stk
413
+ ret %Stack %stack
333
414
  }
334
415
 
335
- define %Sp @pushStack(%Stk %stk, %Sp %oldsp) alwaysinline {
336
- %newstk = load %StkVal, %Stk %stk
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
- %oldstk = call %StkVal @getStk(%Sp %oldsp)
422
+ done:
423
+ store %Stack %oldStack, ptr %stackRest
424
+ ret void
339
425
 
340
- call void @setStk(%StkVal %newstk)
426
+ next:
427
+ tail call void @pushStack(%Stack %rest, %Stack %oldStack)
428
+ ret void
429
+ }
341
430
 
342
- store %StkVal %oldstk, %Stk %stk
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
- %newsp = extractvalue %StkVal %newstk, 1, 0
345
- ret %Sp %newsp
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
- ; pop n+1 stacks
349
- define {%Stk, %Sp} @popStacks(%Sp %oldsp, i64 %n) alwaysinline {
350
- entry:
351
- %oldstk = call %StkVal @getStk(%Sp %oldsp)
352
- br label %loop
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
- loop:
355
- %stkval = phi %StkVal [%oldstk, %entry], [%newstk, %loop]
356
- %i = phi i64 [%n, %entry], [%nexti, %loop]
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
- %newstkp = extractvalue %StkVal %stkval, 3
359
- %newstk = load %StkVal, %Stk %newstkp
461
+ erase:
462
+ %element = load %Pos, ptr %elementPointer
463
+ call void %f(%Pos %element)
360
464
 
361
- %nexti = sub i64 %i, 1
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
- %cmp = icmp eq i64 %i, 0
364
- br i1 %cmp, label %done, label %loop
469
+ return:
470
+ ret void
471
+ }
365
472
 
366
- done:
367
- call void @setStk(%StkVal %newstk)
473
+ define void @eraseRegion(%Region %region) alwaysinline {
474
+ %valuesBase = extractvalue %Region %region, 0, 1
475
+ call void @free(%Base %valuesBase)
368
476
 
369
- store %StkVal %oldstk, %Stk %newstkp
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
- %newsp = extractvalue %StkVal %newstk, 1, 0
372
- %ret.0 = insertvalue {%Stk, %Sp} undef, %Stk %newstkp, 0
373
- %ret.1 = insertvalue {%Stk, %Sp} %ret.0, %Sp %newsp, 1
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 {%Stk, %Sp} %ret.1
487
+ ret void
376
488
  }
377
489
 
378
- define %Sp @underflowStack(%Sp %sp) alwaysinline {
379
- %stk = load %Stk, ptr @rest
380
- %newstk = load %StkVal, %Stk %stk
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
- call void @setStk(%StkVal %newstk)
495
+ %memory = load %Memory, ptr %stackMemory
496
+ %region = load %Region, ptr %stackRegion
497
+ %rest = load %Stack, ptr %stackRest
386
498
 
387
- call void @free(%Sp %sp)
388
- call void @free(%Stk %stk)
499
+ call void @eraseMemory(%Memory %memory)
500
+ call void @eraseRegion(%Region %region)
501
+ call void @free(%Stack %stack)
389
502
 
390
- %newsp = extractvalue %StkVal %newstk, 1, 0
391
- ret %Sp %newsp
503
+ ret %Stack %rest
392
504
  }
393
505
 
394
- define %Mem @copyMem(%Mem %mem) alwaysinline {
395
- %sp = extractvalue %Mem %mem, 0
396
- %base = extractvalue %Mem %mem, 1
397
- %limit = extractvalue %Mem %mem, 2
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
- %intsp = ptrtoint %Sp %sp to i64
400
- %intbase = ptrtoint %Base %base to i64
401
- %intlimit = ptrtoint %Limit %limit to i64
402
- %used = sub i64 %intsp, %intbase
403
- %size = sub i64 %intlimit, %intbase
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
- %newbase = call ptr @malloc(i64 %size)
406
- %intnewbase = ptrtoint %Base %newbase to i64
407
- %intnewsp = add i64 %intnewbase, %used
408
- %intnewlimit = add i64 %intnewbase, %size
409
- %newsp = inttoptr i64 %intnewsp to %Sp
410
- %newlimit = inttoptr i64 %intnewlimit to %Limit
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 %newbase, ptr %base, i64 %used)
524
+ call void @memcpy(ptr %newBase, ptr %base, i64 %used)
413
525
 
414
- %mem.0 = insertvalue %Mem undef, %Sp %newsp, 0
415
- %mem.1 = insertvalue %Mem %mem.0, %Base %newbase, 1
416
- %mem.2 = insertvalue %Mem %mem.1, %Limit %newlimit, 2
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 %Mem %mem.2
530
+ ret %Memory %memory.2
419
531
  }
420
532
 
421
533
  define %Region @copyRegion(%Region %region) alwaysinline {
422
- %mem.0 = extractvalue %Region %region, 0
423
- %mem.1 = extractvalue %Region %region, 1
424
- %mem.2 = extractvalue %Region %region, 2
534
+ %memory.0 = extractvalue %Region %region, 0
535
+ %memory.1 = extractvalue %Region %region, 1
536
+ %memory.2 = extractvalue %Region %region, 2
425
537
 
426
- %objectsbase = extractvalue %Region %region, 1, 1
427
- %objectssp = extractvalue %Region %region, 1, 0
428
- call void @forEachObject(%Base %objectsbase, %Sp %objectssp, %Eraser @sharePositive)
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
- %stringsbase = extractvalue %Region %region, 2, 1
431
- %stringssp = extractvalue %Region %region, 2, 0
432
- call void @forEachObject(%Base %stringsbase, %Sp %stringssp, %Eraser @c_buffer_refcount_increment)
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
- %newmem.0 = call %Mem @copyMem(%Mem %mem.0)
435
- %newmem.1 = call %Mem @copyMem(%Mem %mem.1)
436
- %newmem.2 = call %Mem @copyMem(%Mem %mem.2)
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, %Mem %newmem.0, 0
439
- %region.1 = insertvalue %Region %region.0, %Mem %newmem.1, 1
440
- %region.2 = insertvalue %Region %region.1, %Mem %newmem.2, 2
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 %Stk @uniqueStack(%Stk %stk) alwaysinline {
557
+ define %Stack @uniqueStack(%Stack %stack) alwaysinline {
446
558
 
447
559
  entry:
448
- %stkrc = getelementptr %StkVal, %Stk %stk, i64 0, i32 0
449
- %rc = load %Rc, ptr %stkrc
450
- switch %Rc %rc, label %copy [%Rc 0, label %done]
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 %Stk %stk
565
+ ret %Stack %stack
454
566
 
455
567
  copy:
456
- %newoldrc = sub %Rc %rc, 1
457
- store %Rc %newoldrc, ptr %stkrc
568
+ %newOldReferenceCount = sub %ReferenceCount %referenceCount, 1
569
+ store %ReferenceCount %newOldReferenceCount, ptr %stackReferenceCount
458
570
 
459
- %newhead = call ptr @malloc(i64 112)
571
+ %newHead = call ptr @malloc(i64 120)
460
572
  br label %loop
461
573
 
462
574
  loop:
463
- %old = phi %Stk [%stk, %copy], [%rest, %next]
464
- %newstk = phi %Stk [%newhead, %copy], [%nextnew, %next]
575
+ %old = phi %Stack [%stack, %copy], [%rest, %next]
576
+ %newStack = phi %Stack [%newHead, %copy], [%nextNew, %next]
465
577
 
466
- %stkmem = getelementptr %StkVal, %Stk %old, i64 0, i32 1
467
- %stkregion = getelementptr %StkVal, %Stk %old, i64 0, i32 2
468
- %stkrest = getelementptr %StkVal, %Stk %old, i64 0, i32 3
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
- %mem = load %Mem, ptr %stkmem
471
- %region = load %Region, ptr %stkregion
472
- %rest = load %Stk, ptr %stkrest
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
- %newstkrc = getelementptr %StkVal, %Stk %newstk, i64 0, i32 0
475
- %newstkmem = getelementptr %StkVal, %Stk %newstk, i64 0, i32 1
476
- %newstkregion = getelementptr %StkVal, %Stk %newstk, i64 0, i32 2
477
- %newstkrest = getelementptr %StkVal, %Stk %newstk, i64 0, i32 3
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
- %newmem = call %Mem @copyMem(%Mem %mem)
594
+ %newMemory = call %Memory @copyMemory(%Memory %memory)
480
595
 
481
- %newsp = extractvalue %Mem %newmem, 0
482
- call fastcc void @shareFrames(%Sp %newsp)
596
+ %newStackPointer = extractvalue %Memory %newMemory, 0
597
+ call void @shareFrames(%StackPointer %newStackPointer)
483
598
 
484
- %newregion = call %Region @copyRegion(%Region %region)
599
+ %newRegion = call %Region @copyRegion(%Region %region)
485
600
 
486
- store %Rc 0, ptr %newstkrc
487
- store %Mem %newmem, ptr %newstkmem
488
- store %Region %newregion, ptr %newstkregion
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
- %last = icmp eq %Stk %rest, %stk
491
- br i1 %last, label %closecycle, label %next
606
+ %isNull = icmp eq %Stack %rest, null
607
+ br i1 %isNull, label %stop, label %next
492
608
 
493
609
  next:
494
- %nextnew = call ptr @malloc(i64 112)
495
- store %Stk %nextnew, ptr %newstkrest
610
+ %nextNew = call ptr @malloc(i64 120)
611
+ store %Stack %nextNew, ptr %newStackRest
496
612
  br label %loop
497
613
 
498
- closecycle:
499
- store %Stk %newhead, ptr %newstkrest
500
- ret %Stk %newhead
501
-
614
+ stop:
615
+ store %Stack null, ptr %newStackRest
616
+ ret %Stack %newHead
502
617
  }
503
618
 
504
- define void @shareStack(%Stk %stk) alwaysinline {
505
- %stkrc = getelementptr %StkVal, %Stk %stk, i64 0, i32 0
506
- %rc = load %Rc, ptr %stkrc
507
- %rc.1 = add %Rc %rc, 1
508
- store %Rc %rc.1, ptr %stkrc
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(%Stk %stk) alwaysinline {
513
- %stkrc = getelementptr %StkVal, %Stk %stk, i64 0, i32 0
514
- %rc = load %Rc, ptr %stkrc
515
- switch %Rc %rc, label %decr [%Rc 0, label %free]
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
- %rc.1 = sub %Rc %rc, 1
519
- store %Rc %rc.1, ptr %stkrc
633
+ %referenceCount.1 = sub %ReferenceCount %referenceCount, 1
634
+ store %ReferenceCount %referenceCount.1, ptr %stackReferenceCount
520
635
  ret void
521
636
 
522
637
  free:
523
- %stksp = getelementptr %StkVal, %Stk %stk, i64 0, i32 1, i32 0
524
- %sp = load %Sp, ptr %stksp
525
- call fastcc void @eraseFrames(%Sp %sp)
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
- %regionp = getelementptr %StkVal, %Stk %stk, i64 0, i32 2
528
- %region = load %Region, ptr %regionp
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
- call void @free(%Stk %stk)
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 fastcc void @shareFrames(%Sp %sp) alwaysinline {
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
+ 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 fastcc void @eraseFrames(%Sp %sp) alwaysinline {
545
- %newsp = getelementptr %FrameHeader, %Sp %sp, i64 -1
546
- %stkeraser = getelementptr %FrameHeader, %Sp %newsp, i64 0, i32 2
547
- %eraser = load %Eraser, ptr %stkeraser
548
- tail call fastcc void %eraser(%Sp %newsp)
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
- define void @forEachObject(ptr %elementp, ptr %end, ptr %f) alwaysinline {
553
- %done = icmp uge ptr %elementp, %end
554
- br i1 %done, label %return, label %erase
677
+ ; RTS initialization
555
678
 
556
- erase:
557
- %element = load %Pos, ptr %elementp
558
- call void %f(%Pos %element)
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
- %nextelementp = getelementptr %Pos, ptr %elementp, i64 1
561
- tail call void @forEachObject(ptr %nextelementp, ptr %end, ptr %f)
685
+ define void @topLevelSharer(%Environment %environment) {
686
+ ; TODO this should never be called
562
687
  ret void
688
+ }
563
689
 
564
- return:
690
+ define void @topLevelEraser(%Environment %environment) {
691
+ ; TODO this should never be called
565
692
  ret void
566
693
  }
567
694
 
568
- define void @eraseRegion(%Region %region) alwaysinline {
569
- %valuesbase = extractvalue %Region %region, 0, 1
570
- call void @free(%Base %valuesbase)
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
- %objectsbase = extractvalue %Region %region, 1, 1
573
- %objectssp = extractvalue %Region %region, 1, 0
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
- %stringsbase = extractvalue %Region %region, 2, 1
578
- %stringssp = extractvalue %Region %region, 2, 0
579
- call void @forEachObject(%Base %stringsbase, %Sp %stringssp, %Eraser @c_buffer_refcount_decrement)
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
- ret void
583
- }
707
+ store %ReturnAddress @topLevel, ptr %returnAddressPointer
708
+ store %Sharer @topLevelSharer, ptr %sharerPointer
709
+ store %Eraser @topLevelEraser, ptr %eraserPointer
584
710
 
585
- ; RTS initialization
711
+ %stackPointer_2 = getelementptr %FrameHeader, %StackPointer %stackPointer, i64 1
712
+ store %StackPointer %stackPointer_2, ptr %stackStackPointer
586
713
 
587
- define fastcc void @topLevel(%Env %env, %Sp noalias %sp) {
588
- %base = load %Base, ptr @base
589
- call void @free(%Base %base)
714
+ ret %Stack %stack
715
+ }
590
716
 
591
- %region = load %Region, ptr @region
592
- %base.0 = extractvalue %Region %region, 0, 1
593
- %base.1 = extractvalue %Region %region, 1, 1
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
- call void @free(%Base %base.0)
597
- call void @free(%Base %base.1)
598
- call void @free(%Base %base.2)
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 void @free(%Env %env)
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 fastcc void @topLevelEraser(%Env %env) {
610
- ; TODO this should never be called
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
- ; Primitive Types
748
+ define void @run(%Neg %f) {
749
+ ; fresh stack
750
+ %stack = call %Stack @withEmptyStack()
615
751
 
616
- %Int = type i64
617
- %Double = type double
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
- %Evi = type i64
758
+ ; call
759
+ tail call tailcc %Pos %functionPointer(%Object %object, %Stack %stack)
760
+ ret void
761
+ }