@effekt-lang/effekt 0.19.0 → 0.21.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.
@@ -55,9 +55,6 @@
55
55
  %ReturnAddress = type ptr
56
56
  %FrameHeader = type { %ReturnAddress, %Sharer, %Eraser }
57
57
 
58
- ; Pointers for a heap allocated stack
59
- %Memory = type { %StackPointer, %Base, %Limit }
60
-
61
58
  ; Unique address for each handler.
62
59
  %Prompt = type ptr
63
60
 
@@ -74,7 +71,7 @@
74
71
  ; This is used for two purposes:
75
72
  ; - a refied first-class list of stacks (cyclic linked-list)
76
73
  ; - as part of an intrusive linked-list of stacks (meta stack)
77
- %StackValue = type { %ReferenceCount, %Memory, %Prompt, %Stack }
74
+ %StackValue = type { %ReferenceCount, %StackPointer, %Limit, %Prompt, %Stack }
78
75
 
79
76
 
80
77
 
@@ -146,7 +143,7 @@ define ccc %Neg @unbox(%Pos %input) {
146
143
  ; Prompts
147
144
 
148
145
  define private %Prompt @currentPrompt(%Stack %stack) {
149
- %prompt_pointer = getelementptr %StackValue, ptr %stack, i64 0, i32 2
146
+ %prompt_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 3
150
147
  %prompt = load %Prompt, ptr %prompt_pointer
151
148
  ret %Prompt %prompt
152
149
  }
@@ -154,7 +151,7 @@ define private %Prompt @currentPrompt(%Stack %stack) {
154
151
  define private %Prompt @freshPrompt() {
155
152
  %promptSize = ptrtoint ptr getelementptr (%PromptValue, ptr null, i64 1) to i64
156
153
  %prompt = call %Prompt @malloc(i64 %promptSize)
157
- store %PromptValue zeroinitializer, %Prompt %prompt
154
+ store %PromptValue zeroinitializer, %Prompt %prompt, !alias.scope !4
158
155
  ret %Prompt %prompt
159
156
  }
160
157
 
@@ -247,7 +244,7 @@ define void @eraseNegative(%Neg %val) alwaysinline {
247
244
 
248
245
  define private %Stack @getStack(%Prompt %prompt) {
249
246
  %stack_pointer = getelementptr %PromptValue, %Prompt %prompt, i64 0, i32 1
250
- %stack = load %Stack, ptr %stack_pointer
247
+ %stack = load %Stack, ptr %stack_pointer, !alias.scope !4
251
248
  ret %Stack %stack
252
249
  }
253
250
 
@@ -256,21 +253,16 @@ define private ptr @getVarPointer(%Reference %reference, %Stack %stack) {
256
253
  %offset = extractvalue %Reference %reference, 1
257
254
 
258
255
  %targetStack = call %Stack @getStack(%Prompt %prompt)
259
- %base_pointer = getelementptr %StackValue, %Stack %targetStack, i64 0, i32 1, i32 1
260
- %base = load %Base, ptr %base_pointer
261
- %varPointer = getelementptr i8, %Base %base, i64 %offset
256
+ %varPointer = getelementptr i8, %Base %targetStack, i64 %offset
262
257
  ret ptr %varPointer
263
258
  }
264
259
 
265
260
  define private %Reference @newReference(%Stack %stack) alwaysinline {
266
- %stackPointer_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 1, i32 0
267
- %base_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 1, i32 1
268
-
261
+ %stackPointer_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 1
269
262
  %stackPointer = load %StackPointer, ptr %stackPointer_pointer
270
- %base = load %StackPointer, ptr %base_pointer
271
263
 
272
264
  %intStack = ptrtoint %StackPointer %stackPointer to i64
273
- %intBase = ptrtoint %StackPointer %base to i64
265
+ %intBase = ptrtoint %Stack %stack to i64
274
266
 
275
267
  %offset = sub i64 %intStack, %intBase
276
268
 
@@ -284,55 +276,69 @@ define private %Reference @newReference(%Stack %stack) alwaysinline {
284
276
 
285
277
  ; Stack management
286
278
 
287
- define private %StackPointer @stackAllocate(%Stack %stack, i64 %n) {
288
- %stackPointer_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 1, i32 0
289
- %limit_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 1, i32 2
279
+ define private %Stack @checkLimit(%Stack %stack, i64 %n) alwaysinline {
280
+ %stackPointer_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 1
281
+ %limit_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 2
290
282
 
291
- %currentStackPointer = load %StackPointer, ptr %stackPointer_pointer, !alias.scope !2
292
- %limit = load %Limit, ptr %limit_pointer, !alias.scope !2
283
+ %currentStackPointer = load %StackPointer, ptr %stackPointer_pointer, !alias.scope !3
284
+ %limit = load %Limit, ptr %limit_pointer, !alias.scope !3
293
285
  %nextStackPointer = getelementptr i8, %StackPointer %currentStackPointer, i64 %n
294
286
  %isInside = icmp ule %StackPointer %nextStackPointer, %limit
295
- br i1 %isInside, label %continue, label %realloc
287
+ br i1 %isInside, label %done, label %realloc
296
288
 
297
- continue:
298
- store %StackPointer %nextStackPointer, ptr %stackPointer_pointer, !alias.scope !2
299
- ret %StackPointer %currentStackPointer
289
+ done:
290
+ ret %Stack %stack
300
291
 
301
292
  realloc:
302
- %base_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 1, i32 1
303
- %base = load %Base, ptr %base_pointer, !alias.scope !2
304
-
305
293
  %intStackPointer = ptrtoint %StackPointer %currentStackPointer to i64
306
- %intBase = ptrtoint %Base %base to i64
294
+ %intBase = ptrtoint %Stack %stack to i64
307
295
 
308
296
  %size = sub i64 %intStackPointer, %intBase
309
297
  %nextSize = add i64 %size, %n
310
298
  %newSize = call i64 @nextPowerOfTwo(i64 %nextSize)
311
299
 
312
- %newBase = call ptr @realloc(ptr %base, i64 %newSize)
313
- %newLimit = getelementptr i8, %Base %newBase, i64 %newSize
314
- %newStackPointer = getelementptr i8, %Base %newBase, i64 %size
315
- %newNextStackPointer = getelementptr i8, %StackPointer %newStackPointer, i64 %n
300
+ %newStack = call ptr @realloc(ptr %stack, i64 %newSize)
301
+ %newLimit = getelementptr i8, %Base %newStack, i64 %newSize
302
+ %newStackPointer = getelementptr i8, %Base %newStack, i64 %size
316
303
 
317
- store %StackPointer %newNextStackPointer, ptr %stackPointer_pointer, !alias.scope !2
318
- store %Base %newBase, ptr %base_pointer, !alias.scope !2
319
- store %Limit %newLimit, ptr %limit_pointer, !alias.scope !2
304
+ %newStackPointer_pointer = getelementptr %StackValue, %Stack %newStack, i64 0, i32 1
305
+ %newLimit_pointer = getelementptr %StackValue, %Stack %newStack, i64 0, i32 2
320
306
 
321
- ret %StackPointer %newStackPointer
307
+ store %StackPointer %newStackPointer, ptr %newStackPointer_pointer, !alias.scope !3
308
+ store %Limit %newLimit, ptr %newLimit_pointer, !alias.scope !3
309
+
310
+ %prompt_pointer = getelementptr %StackValue, %Stack %newStack, i64 0, i32 3
311
+ %prompt = load %Prompt, ptr %prompt_pointer
312
+ %promptStack = getelementptr %PromptValue, %Prompt %prompt, i64 0, i32 1
313
+ store %Stack %newStack, ptr %promptStack, !alias.scope !4
314
+
315
+ ret %Stack %newStack
316
+ }
317
+
318
+ define private %StackPointer @stackAllocate(%Stack %stack, i64 %n) alwaysinline {
319
+ %stackPointer_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 1
320
+ %limit_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 2
321
+
322
+ %currentStackPointer = load %StackPointer, ptr %stackPointer_pointer, !alias.scope !3
323
+ %limit = load %Limit, ptr %limit_pointer, !alias.scope !3
324
+ %nextStackPointer = getelementptr i8, %StackPointer %currentStackPointer, i64 %n
325
+
326
+ store %StackPointer %nextStackPointer, ptr %stackPointer_pointer, !alias.scope !3
327
+ ret %StackPointer %currentStackPointer
322
328
  }
323
329
 
324
330
  define private %StackPointer @stackDeallocate(%Stack %stack, i64 %n) {
325
- %stackPointer_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 1, i32 0
326
- %stackPointer = load %StackPointer, ptr %stackPointer_pointer, !alias.scope !2
331
+ %stackPointer_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 1
332
+ %stackPointer = load %StackPointer, ptr %stackPointer_pointer, !alias.scope !3
327
333
 
328
- %limit_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 1, i32 2
329
- %limit = load %Limit, ptr %limit_pointer, !alias.scope !2
334
+ %limit_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 2
335
+ %limit = load %Limit, ptr %limit_pointer, !alias.scope !3
330
336
  %isInside = icmp ule %StackPointer %stackPointer, %limit
331
337
  call void @llvm.assume(i1 %isInside)
332
338
 
333
339
  %o = sub i64 0, %n
334
340
  %newStackPointer = getelementptr i8, %StackPointer %stackPointer, i64 %o
335
- store %StackPointer %newStackPointer, ptr %stackPointer_pointer, !alias.scope !2
341
+ store %StackPointer %newStackPointer, ptr %stackPointer_pointer, !alias.scope !3
336
342
 
337
343
  ret %StackPointer %newStackPointer
338
344
  }
@@ -345,12 +351,12 @@ define private i64 @nextPowerOfTwo(i64 %x) {
345
351
  }
346
352
 
347
353
  define private void @assumeFrameHeaderWasPopped(%Stack %stack) alwaysinline {
348
- %stackPointer_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 1, i32 0
349
- %stackPointer = load %StackPointer, ptr %stackPointer_pointer, !alias.scope !2
354
+ %stackPointer_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 1
355
+ %stackPointer = load %StackPointer, ptr %stackPointer_pointer, !alias.scope !3
350
356
  %oldStackPointer = getelementptr %FrameHeader, %StackPointer %stackPointer, i64 1
351
357
 
352
- %limit_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 1, i32 2
353
- %limit = load %Limit, ptr %limit_pointer, !alias.scope !2
358
+ %limit_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 2
359
+ %limit = load %Limit, ptr %limit_pointer, !alias.scope !3
354
360
  %isInside = icmp ule %StackPointer %oldStackPointer, %limit
355
361
  call void @llvm.assume(i1 %isInside)
356
362
  ret void
@@ -358,45 +364,33 @@ define private void @assumeFrameHeaderWasPopped(%Stack %stack) alwaysinline {
358
364
 
359
365
  ; Meta-stack management
360
366
 
361
- define private %Memory @newMemory() {
362
- %size = shl i64 1, 6
363
- %stackPointer = call %StackPointer @malloc(i64 %size)
364
- %limit = getelementptr i8, ptr %stackPointer, i64 %size
365
-
366
- %memory.0 = insertvalue %Memory undef, %StackPointer %stackPointer, 0
367
- %memory.1 = insertvalue %Memory %memory.0, %Base %stackPointer, 1
368
- %memory.2 = insertvalue %Memory %memory.1, %Limit %limit, 2
369
-
370
- ret %Memory %memory.2
371
- }
372
-
373
367
  define private %Stack @reset(%Stack %oldStack) {
374
368
 
375
369
  %prompt = call %Prompt @freshPrompt()
376
370
 
377
- %size = ptrtoint ptr getelementptr (%StackValue, ptr null, i64 1) to i64
371
+ %size = shl i64 1, 7
378
372
  %stack = call ptr @malloc(i64 %size)
373
+ %stackPointer = getelementptr %StackValue, %Stack %stack, i64 1
374
+ %limit = getelementptr i8, ptr %stack, i64 %size
379
375
 
376
+ %stack.0 = insertvalue %StackValue zeroinitializer, %StackPointer %stackPointer, 1
377
+ %stack.1 = insertvalue %StackValue %stack.0, %Limit %limit, 2
378
+ %stack.2 = insertvalue %StackValue %stack.1, %Prompt %prompt, 3
379
+ %stack.3 = insertvalue %StackValue %stack.2, %Stack %oldStack, 4
380
380
 
381
- %stackMemory = call %Memory @newMemory()
382
-
383
- %stack.0 = insertvalue %StackValue zeroinitializer, %Memory %stackMemory, 1
384
- %stack.1 = insertvalue %StackValue %stack.0, %Prompt %prompt, 2
385
- %stack.2 = insertvalue %StackValue %stack.1, %Stack %oldStack, 3
381
+ store %StackValue %stack.3, %Stack %stack
386
382
 
387
- store %StackValue %stack.2, %Stack %stack
388
-
389
- %stack_pointer = getelementptr %PromptValue, %Prompt %prompt, i64 0, i32 1
390
- store %Stack %stack, ptr %stack_pointer
383
+ %promptStack = getelementptr %PromptValue, %Prompt %prompt, i64 0, i32 1
384
+ store %Stack %stack, ptr %promptStack, !alias.scope !4
391
385
 
392
386
  ret %Stack %stack
393
387
  }
394
388
 
395
- define private void @updatePrompts(%Stack %stack) {
396
- %prompt_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 2
389
+ define private void @revalidate(%Stack %stack) {
390
+ %prompt_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 3
397
391
  %prompt = load %Prompt, ptr %prompt_pointer
398
392
  %stack_pointer = getelementptr %PromptValue, %Prompt %prompt, i64 0, i32 1
399
- %promptStack = load %Stack, ptr %stack_pointer
393
+ %promptStack = load %Stack, ptr %stack_pointer, !alias.scope !4
400
394
  %isThis = icmp eq %Stack %promptStack, %stack
401
395
  br i1 %isThis, label %done, label %continue
402
396
 
@@ -408,26 +402,36 @@ continue:
408
402
  br i1 %isOccupied, label %displace, label %update
409
403
 
410
404
  displace:
411
- call void @displace(%Stack %promptStack, %Stack %promptStack)
405
+ call void @invalidate(%Stack %promptStack, %Stack %promptStack)
412
406
  br label %update
413
407
 
414
408
  update:
415
- store %Stack %stack, ptr %stack_pointer
409
+ store %Stack %stack, ptr %stack_pointer, !alias.scope !4
416
410
 
417
- %next_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 3
411
+ %next_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 4
418
412
  %next = load %Stack, ptr %next_pointer
419
- tail call void @updatePrompts(%Stack %next)
413
+ tail call void @revalidate(%Stack %next)
420
414
  ret void
421
415
  }
422
416
 
423
- define private void @displace(%Stack %stack, %Stack %end) {
424
- %prompt_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 2
425
- %next_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 3
417
+ ; This panics if we invalidate the meta stack
418
+ define private void @invalidate(%Stack %stack, %Stack %end) {
419
+ %prompt_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 3
420
+ %next_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 4
426
421
  %prompt = load %Prompt, ptr %prompt_pointer
427
422
  %stack_pointer = getelementptr %PromptValue, %Prompt %prompt, i64 0, i32 1
428
- store %Stack null, ptr %stack_pointer
423
+ store %Stack null, ptr %stack_pointer, !alias.scope !4
429
424
 
430
425
  %next = load %Stack, ptr %next_pointer
426
+
427
+ %isNull = icmp eq %Stack %next, null
428
+ br i1 %isNull, label %error, label %check
429
+
430
+ error:
431
+ call void @duplicated_prompt()
432
+ ret void
433
+
434
+ check:
431
435
  %isEnd = icmp eq %Stack %next, %end
432
436
  br i1 %isEnd, label %done, label %continue
433
437
 
@@ -435,15 +439,15 @@ done:
435
439
  ret void
436
440
 
437
441
  continue:
438
- tail call void @displace(%Stack %next, %Stack %end)
442
+ tail call void @invalidate(%Stack %next, %Stack %end)
439
443
  ret void
440
444
  }
441
445
 
442
446
  define private %Stack @resume(%Resumption %resumption, %Stack %oldStack) {
443
447
  %uniqueResumption = call %Resumption @uniqueStack(%Resumption %resumption)
444
- %rest_pointer = getelementptr %StackValue, %Resumption %uniqueResumption, i64 0, i32 3
448
+ %rest_pointer = getelementptr %StackValue, %Resumption %uniqueResumption, i64 0, i32 4
445
449
  %start = load %Stack, ptr %rest_pointer
446
- call void @updatePrompts(%Stack %start)
450
+ call void @revalidate(%Stack %start)
447
451
 
448
452
  store %Stack %oldStack, ptr %rest_pointer
449
453
 
@@ -452,8 +456,8 @@ define private %Stack @resume(%Resumption %resumption, %Stack %oldStack) {
452
456
 
453
457
  define private {%Resumption, %Stack} @shift(%Stack %stack, %Prompt %prompt) {
454
458
  %resumpion_pointer = getelementptr %PromptValue, %Prompt %prompt, i64 0, i32 1
455
- %resumption = load %Stack, ptr %resumpion_pointer
456
- %next_pointer = getelementptr %StackValue, %Stack %resumption, i64 0, i32 3
459
+ %resumption = load %Stack, ptr %resumpion_pointer, !alias.scope !4
460
+ %next_pointer = getelementptr %StackValue, %Stack %resumption, i64 0, i32 4
457
461
  %next = load %Stack, ptr %next_pointer
458
462
 
459
463
  store %Stack %stack, ptr %next_pointer
@@ -463,20 +467,14 @@ define private {%Resumption, %Stack} @shift(%Stack %stack, %Prompt %prompt) {
463
467
  ret {%Resumption, %Stack} %result
464
468
  }
465
469
 
466
- define private void @eraseMemory(%Memory %memory) {
467
- %stackPointer = extractvalue %Memory %memory, 0
468
- call void @free(%StackPointer %stackPointer)
469
- ret void
470
- }
471
-
472
470
  define private void @erasePrompt(%Prompt %prompt) alwaysinline {
473
471
  %referenceCount_pointer = getelementptr %PromptValue, %Prompt %prompt, i64 0, i32 0
474
- %referenceCount = load %ReferenceCount, ptr %referenceCount_pointer
472
+ %referenceCount = load %ReferenceCount, ptr %referenceCount_pointer, !alias.scope !4
475
473
  switch %ReferenceCount %referenceCount, label %decrement [%ReferenceCount 0, label %free]
476
474
 
477
475
  decrement:
478
476
  %newReferenceCount = sub %ReferenceCount %referenceCount, 1
479
- store %ReferenceCount %newReferenceCount, ptr %referenceCount_pointer
477
+ store %ReferenceCount %newReferenceCount, ptr %referenceCount_pointer, !alias.scope !4
480
478
  ret void
481
479
 
482
480
  free:
@@ -486,25 +484,22 @@ free:
486
484
 
487
485
  define private void @sharePrompt(%Prompt %prompt) alwaysinline {
488
486
  %referenceCount_pointer = getelementptr %PromptValue, %Prompt %prompt, i64 0, i32 0
489
- %referenceCount = load %ReferenceCount, ptr %referenceCount_pointer
487
+ %referenceCount = load %ReferenceCount, ptr %referenceCount_pointer, !alias.scope !4
490
488
  %newReferenceCount = add %ReferenceCount %referenceCount, 1
491
- store %ReferenceCount %newReferenceCount, ptr %referenceCount_pointer
489
+ store %ReferenceCount %newReferenceCount, ptr %referenceCount_pointer, !alias.scope !4
492
490
  ret void
493
491
  }
494
492
 
495
493
  define private %Stack @underflowStack(%Stack %stack) {
496
- %stackMemory = getelementptr %StackValue, %Stack %stack, i64 0, i32 1
497
- %stackPrompt = getelementptr %StackValue, %Stack %stack, i64 0, i32 2
498
- %stackRest = getelementptr %StackValue, %Stack %stack, i64 0, i32 3
494
+ %stackPrompt = getelementptr %StackValue, %Stack %stack, i64 0, i32 3
495
+ %stackRest = getelementptr %StackValue, %Stack %stack, i64 0, i32 4
499
496
 
500
- %memory = load %Memory, ptr %stackMemory
501
497
  %prompt = load %Prompt, ptr %stackPrompt
502
498
  %rest = load %Stack, ptr %stackRest
503
499
 
504
500
  %promptStack_pointer = getelementptr %PromptValue, %Prompt %prompt, i64 0, i32 1
505
- store %Stack null, ptr %promptStack_pointer
501
+ store %Stack null, ptr %promptStack_pointer, !alias.scope !4
506
502
 
507
- call void @eraseMemory(%Memory %memory)
508
503
  call void @erasePrompt(%Prompt %prompt)
509
504
  call void @free(%Stack %stack)
510
505
 
@@ -515,31 +510,41 @@ define private void @nop(%Stack %stack) {
515
510
  ret void
516
511
  }
517
512
 
518
- define private %Memory @copyMemory(%Memory %memory) alwaysinline {
519
- %stackPointer = extractvalue %Memory %memory, 0
520
- %base = extractvalue %Memory %memory, 1
521
- %limit = extractvalue %Memory %memory, 2
513
+ define private %Stack @copyStack(%Stack %stack) alwaysinline {
514
+ %stackPointer_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 1
515
+ %limit_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 2
516
+
517
+ %stackPointer = load %StackPointer, ptr %stackPointer_pointer
518
+ %limit = load %Limit, ptr %limit_pointer
522
519
 
523
520
  %intStackPointer = ptrtoint %StackPointer %stackPointer to i64
524
- %intBase = ptrtoint %Base %base to i64
521
+ %intBase = ptrtoint %Stack %stack to i64
525
522
  %intLimit = ptrtoint %Limit %limit to i64
526
523
  %used = sub i64 %intStackPointer, %intBase
527
524
  %size = sub i64 %intLimit, %intBase
528
525
 
529
- %newBase = call ptr @malloc(i64 %size)
530
- %intNewBase = ptrtoint %Base %newBase to i64
531
- %intNewStackPointer = add i64 %intNewBase, %used
532
- %intNewLimit = add i64 %intNewBase, %size
533
- %newStackPointer = inttoptr i64 %intNewStackPointer to %StackPointer
534
- %newLimit = inttoptr i64 %intNewLimit to %Limit
526
+ %newStack = call ptr @malloc(i64 %size)
527
+ %newStackPointer = getelementptr i8, %Stack %newStack, i64 %used
528
+ %newLimit = getelementptr i8, %Stack %newStack, i64 %size
529
+
530
+ call void @memcpy(ptr %newStack, ptr %stack, i64 %used)
535
531
 
536
- call void @memcpy(ptr %newBase, ptr %base, i64 %used)
532
+ %newStackPointer_pointer = getelementptr %StackValue, %Stack %newStack, i64 0, i32 1
533
+ %newLimit_pointer = getelementptr %StackValue, %Stack %newStack, i64 0, i32 2
537
534
 
538
- %memory.0 = insertvalue %Memory undef, %StackPointer %newStackPointer, 0
539
- %memory.1 = insertvalue %Memory %memory.0, %Base %newBase, 1
540
- %memory.2 = insertvalue %Memory %memory.1, %Limit %newLimit, 2
535
+ store %StackPointer %newStackPointer, ptr %newStackPointer_pointer
536
+ store %Limit %newLimit, ptr %newLimit_pointer
541
537
 
542
- ret %Memory %memory.2
538
+ call void @shareFrames(%StackPointer %newStackPointer)
539
+
540
+ %prompt_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 3
541
+ %prompt = load %Prompt, ptr %prompt_pointer
542
+ call void @sharePrompt(%Prompt %prompt)
543
+
544
+ %referenceCount_pointer = getelementptr %StackValue, %Stack %newStack, i64 0, i32 0
545
+ store i64 0, ptr %referenceCount_pointer
546
+
547
+ ret %Stack %newStack
543
548
  }
544
549
 
545
550
 
@@ -556,53 +561,37 @@ done:
556
561
  copy:
557
562
  %newOldReferenceCount = sub %ReferenceCount %referenceCount, 1
558
563
  store %ReferenceCount %newOldReferenceCount, ptr %referenceCount_pointer
559
- %stack_pointer = getelementptr %StackValue, %Resumption %resumption, i64 0, i32 3
560
- %stack = load %Stack, ptr %stack_pointer
561
564
 
562
- %size = ptrtoint ptr getelementptr (%StackValue, ptr null, i64 1) to i64
563
- %newHead = call ptr @malloc(i64 %size)
565
+ %firstCopy = call %Stack @copyStack(%Stack %resumption)
564
566
 
565
- br label %loop
567
+ %stack_pointer = getelementptr %StackValue, %Resumption %resumption, i64 0, i32 4
568
+ %stack = load %Stack, ptr %stack_pointer
566
569
 
567
- loop:
568
- %old = phi %Stack [%stack, %copy], [%rest, %next]
569
- %newStack = phi %Stack [%newHead, %copy], [%nextNew, %next]
570
+ br label %check
570
571
 
571
- %stackMemory = getelementptr %StackValue, %Stack %old, i64 0, i32 1
572
- %stackPrompt = getelementptr %StackValue, %Stack %old, i64 0, i32 2
573
- %stackRest = getelementptr %StackValue, %Stack %old, i64 0, i32 3
572
+ check:
573
+ %current = phi %Stack [%stack, %copy], [%next, %loop]
574
+ %previousCopy = phi %Stack [%firstCopy, %copy], [%newCopy, %loop]
574
575
 
575
- %memory = load %Memory, ptr %stackMemory
576
- %prompt = load %Prompt, ptr %stackPrompt
577
- %rest = load %Stack, ptr %stackRest
576
+ %rest_pointer = getelementptr %StackValue, %Stack %previousCopy, i64 0, i32 4
578
577
 
579
- %newStackReferenceCounter = getelementptr %StackValue, %Stack %newStack, i64 0, i32 0
580
- %newStackMemory = getelementptr %StackValue, %Stack %newStack, i64 0, i32 1
581
- %newStackPrompt = getelementptr %StackValue, %Stack %newStack, i64 0, i32 2
582
- %newStackRest = getelementptr %StackValue, %Stack %newStack, i64 0, i32 3
578
+ %isEnd = icmp eq %Stack %current, %resumption
579
+ br i1 %isEnd, label %stop, label %loop
583
580
 
584
- %newMemory = call %Memory @copyMemory(%Memory %memory)
585
-
586
- %newStackPointer = extractvalue %Memory %newMemory, 0
587
- call void @shareFrames(%StackPointer %newStackPointer)
581
+ loop:
588
582
 
589
- call void @sharePrompt(%Prompt %prompt)
583
+ %newCopy = call %Stack @copyStack(%Stack %current)
590
584
 
591
- store %ReferenceCount 0, ptr %newStackReferenceCounter
592
- store %Memory %newMemory, ptr %newStackMemory
593
- store %Prompt %prompt, ptr %newStackPrompt
585
+ store %Stack %newCopy, ptr %rest_pointer
594
586
 
595
- %isEnd = icmp eq %Stack %old, %resumption
596
- br i1 %isEnd, label %stop, label %next
587
+ %next_pointer = getelementptr %StackValue, %Stack %current, i64 0, i32 4
588
+ %next = load %Stack, ptr %next_pointer
597
589
 
598
- next:
599
- %nextNew = call ptr @malloc(i64 %size)
600
- store %Stack %nextNew, ptr %newStackRest
601
- br label %loop
590
+ br label %check
602
591
 
603
592
  stop:
604
- store %Stack %newHead, ptr %newStackRest
605
- ret %Stack %newStack
593
+ store %Stack %firstCopy, ptr %rest_pointer
594
+ ret %Stack %firstCopy
606
595
  }
607
596
 
608
597
  define void @shareResumption(%Resumption %resumption) alwaysinline {
@@ -624,7 +613,7 @@ define void @eraseResumption(%Resumption %resumption) alwaysinline {
624
613
  ret void
625
614
 
626
615
  free:
627
- %stack_pointer = getelementptr %StackValue, %Resumption %resumption, i64 0, i32 3
616
+ %stack_pointer = getelementptr %StackValue, %Resumption %resumption, i64 0, i32 4
628
617
  %stack = load %Stack, ptr %stack_pointer
629
618
  store %Stack null, ptr %stack_pointer
630
619
  call void @eraseStack(%Stack %stack)
@@ -632,25 +621,24 @@ define void @eraseResumption(%Resumption %resumption) alwaysinline {
632
621
  }
633
622
 
634
623
  define void @eraseStack(%Stack %stack) alwaysinline {
635
- %stackPointer_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 1, i32 0
636
- %prompt_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 2
637
- %rest_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 3
624
+ %stackPointer_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 1
625
+ %prompt_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 3
626
+ %rest_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 4
638
627
 
639
628
  %stackPointer = load %StackPointer, ptr %stackPointer_pointer
640
629
  %prompt = load %Stack, ptr %prompt_pointer
641
630
  %rest = load %Stack, ptr %rest_pointer
642
631
 
643
632
  %promptStack_pointer = getelementptr %PromptValue, %Prompt %prompt, i64 0, i32 1
644
- %promptStack = load %Stack, ptr %promptStack_pointer
633
+ %promptStack = load %Stack, ptr %promptStack_pointer, !alias.scope !4
645
634
  %isThisStack = icmp eq %Stack %promptStack, %stack
646
635
  br i1 %isThisStack, label %clearPrompt, label %free
647
636
 
648
637
  clearPrompt:
649
- store %Stack null, ptr %promptStack_pointer
638
+ store %Stack null, ptr %promptStack_pointer, !alias.scope !4
650
639
  br label %free
651
640
 
652
641
  free:
653
- call void @free(%Stack %stack)
654
642
  call void @eraseFrames(%StackPointer %stackPointer)
655
643
  call void @erasePrompt(%Prompt %prompt)
656
644
 
@@ -681,12 +669,23 @@ define private void @eraseFrames(%StackPointer %stackPointer) alwaysinline {
681
669
  ret void
682
670
  }
683
671
 
672
+ define private void @freeStack(%StackPointer %stackPointer) alwaysinline {
673
+ %base = getelementptr %StackValue, %StackPointer %stackPointer, i64 -1
674
+ call void @free(%Base %base)
675
+ ret void
676
+ }
677
+
684
678
  ; RTS initialization
685
679
 
686
680
  define private tailcc void @topLevel(%Pos %val, %Stack %stack) {
687
681
  %rest = call %Stack @underflowStack(%Stack %stack)
688
682
  ; rest holds global variables
689
- call void @eraseStack(%Stack %rest)
683
+ call void @resume_Pos(%Stack %rest, %Pos %val)
684
+ ret void
685
+ }
686
+
687
+ define private tailcc void @globalsReturn(%Pos %val, %Stack %stack) {
688
+ %rest = call %Stack @underflowStack(%Stack %stack)
690
689
  ret void
691
690
  }
692
691
 
@@ -705,16 +704,16 @@ define private void @topLevelEraser(%Environment %environment) {
705
704
  define private %Stack @withEmptyStack() {
706
705
  %globals = call %Stack @reset(%Stack null)
707
706
 
708
- %globalsStackPointer_pointer = getelementptr %StackValue, %Stack %globals, i64 0, i32 1, i32 0
707
+ %globalsStackPointer_pointer = getelementptr %StackValue, %Stack %globals, i64 0, i32 1
709
708
  %globalsStackPointer = load %StackPointer, ptr %globalsStackPointer_pointer
710
709
 
711
710
  %returnAddressPointer.0 = getelementptr %FrameHeader, %StackPointer %globalsStackPointer, i64 0, i32 0
712
711
  %sharerPointer.0 = getelementptr %FrameHeader, %StackPointer %globalsStackPointer, i64 0, i32 1
713
712
  %eraserPointer.0 = getelementptr %FrameHeader, %StackPointer %globalsStackPointer, i64 0, i32 2
714
713
 
715
- store ptr @nop, ptr %returnAddressPointer.0
716
- store ptr @nop, ptr %sharerPointer.0
717
- store ptr @free, ptr %eraserPointer.0
714
+ store ptr @globalsReturn, ptr %returnAddressPointer.0
715
+ store ptr @topLevelSharer, ptr %sharerPointer.0
716
+ store ptr @topLevelEraser, ptr %eraserPointer.0
718
717
 
719
718
  %globalsStackPointer_2 = getelementptr %FrameHeader, %StackPointer %globalsStackPointer, i64 1
720
719
  store %StackPointer %globalsStackPointer_2, ptr %globalsStackPointer_pointer
@@ -722,9 +721,9 @@ define private %Stack @withEmptyStack() {
722
721
  %stack = call %Stack @reset(%Stack %globals)
723
722
 
724
723
  %globalStack = getelementptr %PromptValue, %Prompt @global, i64 0, i32 1
725
- store %Stack %stack, ptr %globalStack
724
+ store %Stack %stack, ptr %globalStack, !alias.scope !4
726
725
 
727
- %stackStackPointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 1, i32 0
726
+ %stackStackPointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 1
728
727
  %stackPointer = load %StackPointer, ptr %stackStackPointer
729
728
 
730
729
  %returnAddressPointer = getelementptr %FrameHeader, %StackPointer %stackPointer, i64 0, i32 0
@@ -808,6 +807,9 @@ define void @run_Pos(%Neg %f, %Pos %argument) {
808
807
 
809
808
  ; Scopes
810
809
  !1 = !{!"stackValues", !0}
810
+ !2 = !{!"prompts", !0}
811
811
 
812
812
  ; Scope lists
813
- !2 = !{!1}
813
+ !3 = !{!1} ; stackValues
814
+ !4 = !{!2} ; prompts
815
+ !5 = !{!1, !2} ; stackValues & prompts
@@ -1,4 +1,4 @@
1
- <!doctype html><html lang=en><head><meta charset=utf-8><meta http-equiv=x-ua-compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><title>Eclipse Public License 2.0 (EPL) | The Eclipse Foundation</title><meta property="og:title" content="Eclipse Public License 2.0 (EPL) | The Eclipse Foundation"><meta name=twitter:title content="Eclipse Public License 2.0 (EPL) | The Eclipse Foundation"><meta name=description content="The Eclipse Foundation provides our global community of individuals and organisations with a mature, scalable, and business-friendly environment for open source …"><meta property="og:description" content="The Eclipse Foundation provides our global community of individuals and organisations with a mature, scalable, and business-friendly environment for open source …"><meta name=twitter:description content="The Eclipse Foundation provides our global community of individuals and organisations with a mature, scalable, and business-friendly environment for open source …"><meta name=author content="Wayne Beaton"><link href=/favicon.ico rel=icon type=image/x-icon><meta property="og:image" content="https://www.eclipse.org/images/logos/eclipse-foundation-400x400.png"><meta name=twitter:image content="https://www.eclipse.org/images/logos/eclipse-foundation-400x400.png"><meta name=twitter:card content="summary"><meta name=twitter:site content="@eclipsefdn"><meta name=twitter:creator content="@eclipsefdn"><meta property="og:url" content="https://www.eclipse.org/legal/epl-2.0/"><meta property="og:type" content="website"><meta property="og:site_name" content="Eclipse Foundation"><meta name=keywords content="epl,epl-2.0,legal,foundation,eclipse,eclipse public license,license,licenses"><meta name=generator content="Hugo 0.110.0"><link rel=canonical href=https://www.eclipse.org/legal/epl-2.0/><link rel=alternate href=/legal/epl-2.0/index.xml type=application/rss+xml title><link rel=stylesheet href="/public/css/styles.css?v=1737918922"><script>(function(e,t,n,s,o){e[s]=e[s]||[],e[s].push({"gtm.start":(new Date).getTime(),event:"gtm.js"});var a=t.getElementsByTagName(n)[0],i=t.createElement(n),r=s!="dataLayer"?"&l="+s:"";i.async=!0,i.src="https://www.googletagmanager.com/gtm.js?id="+o+r,a.parentNode.insertBefore(i,a)})(window,document,"script","dataLayer","GTM-5WLCZXC")</script><script>var tableClasses="table"</script><link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap" rel=stylesheet type=text/css></head><body><noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-5WLCZXC" height=0 width=0 style=display:none;visibility:hidden></iframe></noscript><a class=sr-only href=#content>Skip to main content</a><header class="header-wrapper header-wrapper" id=header><div class=header-toolbar><div class=container><div class=header-toolbar-row><div class="toolbar-btn toolbar-search-btn dropdown"><button class=dropdown-toggle id=toolbar-search type=button data-toggle=dropdown tabindex=0 aria-label=Search>
1
+ <!doctype html><html lang=en><head><meta charset=utf-8><meta http-equiv=x-ua-compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><title>Eclipse Public License 2.0 (EPL) | The Eclipse Foundation</title><meta property="og:title" content="Eclipse Public License 2.0 (EPL) | The Eclipse Foundation"><meta name=twitter:title content="Eclipse Public License 2.0 (EPL) | The Eclipse Foundation"><meta name=description content="The Eclipse Foundation provides our global community of individuals and organisations with a mature, scalable, and business-friendly environment for open source …"><meta property="og:description" content="The Eclipse Foundation provides our global community of individuals and organisations with a mature, scalable, and business-friendly environment for open source …"><meta name=twitter:description content="The Eclipse Foundation provides our global community of individuals and organisations with a mature, scalable, and business-friendly environment for open source …"><meta name=author content="Wayne Beaton"><link href=/favicon.ico rel=icon type=image/x-icon><meta property="og:image" content="https://www.eclipse.org/images/logos/eclipse-foundation-400x400.png"><meta name=twitter:image content="https://www.eclipse.org/images/logos/eclipse-foundation-400x400.png"><meta name=twitter:card content="summary"><meta name=twitter:site content="@eclipsefdn"><meta name=twitter:creator content="@eclipsefdn"><meta property="og:url" content="https://www.eclipse.org/legal/epl-2.0/"><meta property="og:type" content="website"><meta property="og:site_name" content="Eclipse Foundation"><meta name=keywords content="epl,epl-2.0,legal,foundation,eclipse,eclipse public license,license,licenses"><meta name=generator content="Hugo 0.110.0"><link rel=canonical href=https://www.eclipse.org/legal/epl-2.0/><link rel=alternate href=/legal/epl-2.0/index.xml type=application/rss+xml title><link rel=stylesheet href="/public/css/styles.css?v=1739733342"><script>(function(e,t,n,s,o){e[s]=e[s]||[],e[s].push({"gtm.start":(new Date).getTime(),event:"gtm.js"});var a=t.getElementsByTagName(n)[0],i=t.createElement(n),r=s!="dataLayer"?"&l="+s:"";i.async=!0,i.src="https://www.googletagmanager.com/gtm.js?id="+o+r,a.parentNode.insertBefore(i,a)})(window,document,"script","dataLayer","GTM-5WLCZXC")</script><script>var tableClasses="table"</script><link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap" rel=stylesheet type=text/css></head><body><noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-5WLCZXC" height=0 width=0 style=display:none;visibility:hidden></iframe></noscript><a class=sr-only href=#content>Skip to main content</a><header class="header-wrapper header-wrapper" id=header><div class=header-toolbar><div class=container><div class=header-toolbar-row><div class="toolbar-btn toolbar-search-btn dropdown"><button class=dropdown-toggle id=toolbar-search type=button data-toggle=dropdown tabindex=0 aria-label=Search>
2
2
  <i class="fa fa-search fa-lg" aria-role=none></i></button><div class="toolbar-search-bar-wrapper dropdown-menu dropdown-menu-right" aria-labelledby=toolbar-search><form action=https://www.eclipse.org/home/search method=get><div class=search-bar><input class=search-bar-input name=q placeholder=Search>
3
3
  <button>
4
4
  <i class="fa fa-search" type=submit></i></button></div></form></div></div><div class="toolbar-btn toolbar-user-menu-btn dropdown"><button class=dropdown-toggle id=toolbar-user-menu type=button data-toggle=dropdown tabindex=0 aria-label="User Menu">
@@ -55,7 +55,7 @@ open source software collaboration and innovation.</p></div><div class=mega-menu
55
55
  <i class="fa-brands fa-youtube fa-stack-1x fa-inverse" aria-hidden=true></i>
56
56
  <span class=sr-only>Youtube account</span></span></a></li><li><a class=link-unstyled href=https://www.linkedin.com/company/eclipse-foundation title="Linkedin account"><span class=fa-stack><i class="fa-solid fa-circle fa-stack-2x" aria-hidden=true></i>
57
57
  <i class="fa-brands fa-linkedin-in fa-stack-1x fa-inverse" aria-hidden=true></i>
58
- <span class=sr-only>Linkedin account</span></span></a></li></ul></div></div><div class="footer-sections row equal-height-md font-bold"><div class=col-md-15><div class=row><section id=footer-eclipse-foundation class="footer-section col-sm-8"><div class=menu-heading>Eclipse Foundation</div><ul class=nav><li><a href=https://www.eclipse.org/org/>About</a></li><li><a href=https://projects.eclipse.org/>Projects</a></li><li><a href=https://www.eclipse.org/collaborations/>Collaborations</a></li><li><a href=https://www.eclipse.org/membership/>Membership</a></li><li><a href=https://www.eclipse.org/sponsor/>Sponsor</a></li></ul></section><section id=footer-legal class="footer-section col-sm-8"><div class=menu-heading>Legal</div><ul class=nav><li><a href=https://www.eclipse.org/legal/privacy/>Privacy Policy</a></li><li><a href=https://www.eclipse.org/legal/terms-of-use/>Terms of Use</a></li><li><a href=https://www.eclipse.org/legal/compliance/>Compliance</a></li><li><a href=https://www.eclipse.org/org/documents/Community_Code_of_Conduct.php>Code of Conduct</a></li><li><a href=https://www.eclipse.org/legal/>Legal Resources</a></li><li><a class=toolbar-manage-cookies href=# onclick=event.preventDefault()>Manage Cookies</a></li></ul></section><section id=footer-more class="footer-section col-sm-8"><div class=menu-heading>More</div><ul class=nav><li><a href=https://www.eclipse.org/security/>Report a Vulnerability</a></li><li><a href=https://status.eclipse.org/>Service Status</a></li><li><a href=https://www.eclipse.org/org/foundation/contact.php>Contact Us</a></li><li><a href=https://www.eclipse.org/projects/support/>Support</a></li></ul></section></div></div><div id=footer-end class="footer-section col-md-8 col-md-offset-1 col-sm-24"><div class=footer-end-newsletter><form id=mc-embedded-subscribe-form action=https://eclipsecon.us6.list-manage.com/subscribe/post method=post novalidate target=_blank><label class=footer-end-newsletter-label for=email>Subscribe to our Newsletter</label><div class=footer-end-newsletter-input-wrapper><input class=footer-end-newsletter-input type=email id=email name=EMAIL autocomplete=email placeholder="Enter your email address"><div><i class="fa fa-solid fa-envelope fa-lg" aria-hidden=true></i></div></div><input type=hidden name=u value=eaf9e1f06f194eadc66788a85>
59
- <input type=hidden name=id value=46e57eacf1>
60
- <input id=mc-embedded-subscribe type=submit name=subscribe hidden></form></div></div></div><div class="col-sm-24 margin-top-20"><div class=row><div id=copyright class=col-md-16><p id=copyright-text>Copyright &copy; Eclipse Foundation AISBL. All Rights Reserved.</p></div></div></div><a href=# class=scrollup>Back to the top</a></div></footer><div id=footer-js><script src="/public/js/main.js?v1.0?v=1737918922"></script>
58
+ <span class=sr-only>Linkedin account</span></span></a></li></ul></div></div><div class="footer-sections row equal-height-md font-bold"><div class=col-md-15><div class=row><section id=footer-eclipse-foundation class="footer-section col-sm-8"><div class=menu-heading>Eclipse Foundation</div><ul class=nav><li><a href=https://www.eclipse.org/org/>About</a></li><li><a href=https://projects.eclipse.org/>Projects</a></li><li><a href=https://www.eclipse.org/collaborations/>Collaborations</a></li><li><a href=https://www.eclipse.org/membership/>Membership</a></li><li><a href=https://www.eclipse.org/sponsor/>Sponsor</a></li></ul></section><section id=footer-legal class="footer-section col-sm-8"><div class=menu-heading>Legal</div><ul class=nav><li><a href=https://www.eclipse.org/legal/privacy/>Privacy Policy</a></li><li><a href=https://www.eclipse.org/legal/terms-of-use/>Terms of Use</a></li><li><a href=https://www.eclipse.org/legal/compliance/>Compliance</a></li><li><a href=https://www.eclipse.org/org/documents/Community_Code_of_Conduct.php>Code of Conduct</a></li><li><a href=https://www.eclipse.org/legal/>Legal Resources</a></li><li><a class=toolbar-manage-cookies href=# onclick=event.preventDefault()>Manage Cookies</a></li></ul></section><section id=footer-more class="footer-section col-sm-8"><div class=menu-heading>More</div><ul class=nav><li><a href=https://www.eclipse.org/security/>Report a Vulnerability</a></li><li><a href=https://status.eclipse.org/>Service Status</a></li><li><a href=https://www.eclipse.org/org/foundation/contact.php>Contact Us</a></li><li><a href=https://www.eclipse.org/projects/support/>Support</a></li></ul></section></div></div><div id=footer-end class="footer-section col-md-8 col-md-offset-1 col-sm-24"><div class=footer-end-newsletter><form id=mc-embedded-subscribe-form action="https://eclipse.us6.list-manage.com/subscribe/post?u=eaf9e1f06f194eadc66788a85&id=e7538485cd&f_id=00f9c2e1f0" method=post novalidate target=_blank><label class=footer-end-newsletter-label for=email>Subscribe to our Newsletter</label><div class=footer-end-newsletter-input-wrapper><input class=footer-end-newsletter-input type=email id=email name=EMAIL autocomplete=email placeholder="Enter your email address">
59
+ <button class="footer-end-newsletter-submit btn btn-link" id=mc-embedded-subscribe type=submit name=subscribe>
60
+ <i class="fa fa-solid fa-envelope fa-lg" aria-hidden=true></i></button></div></form></div></div></div><div class="col-sm-24 margin-top-20"><div class=row><div id=copyright class=col-md-16><p id=copyright-text>Copyright &copy; Eclipse Foundation AISBL. All Rights Reserved.</p></div></div></div><a href=# class=scrollup>Back to the top</a></div></footer><div id=footer-js><script src="/public/js/main.js?v1.0?v=1739733342"></script>
61
61
  <script>(function(){})(jQuery,document)</script></div></body></html>