@effekt-lang/effekt 0.2.2 → 0.4.0

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