From 5ef9597631302f6288e5e26d52fde957bfebd237 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Mon, 23 Sep 2019 09:21:40 -0700 Subject: 5687 Move stack operations to a layer of their own. It was some short-term pain to take out the syntax sugar from it, but we need access to this layer from braces, which can't depend on sugar since it's part of sugar. Just simpler to keep one clear line and not have to build sometimes with some sugar but not others. --- apps/braces.subx | 274 ------------------------------------------------------- 1 file changed, 274 deletions(-) (limited to 'apps/braces.subx') diff --git a/apps/braces.subx b/apps/braces.subx index 0b70c7a0..32042539 100644 --- a/apps/braces.subx +++ b/apps/braces.subx @@ -376,277 +376,3 @@ test-subx-braces-2: 89/<- %esp 5/r32/ebp 5d/pop-to-ebp c3/return - -# let's just put stack primitives here for now -# we need to think about how to maintain layers of the library at different levels of syntax sugar - -# A stack looks like this: -# top: int -# data: (array byte) # prefixed by length as usual - -clear-stack: # s : (address stack) - # . prolog - 55/push-ebp - 89/<- %ebp 4/r32/esp - # . save registers - 50/push-eax - 51/push-ecx - # eax = s - 8b/-> *(ebp+8) 0/r32/eax - # ecx = s->length - 8b/-> *(eax+4) 1/r32/ecx - # ecx = &s->data[s->length] - 8d/copy-address *(eax+ecx+8) 1/r32/ecx - # s->top = 0 - c7/copy 0/subop/copy *eax 0/imm32 - # eax = s->data - 81 0/subop/add %eax 8/imm32 -$clear-stack:loop: - # if (eax >= ecx) break - 39/compare %eax 1/r32/ecx - 73/jump-if-greater-or-equal-unsigned $clear-stack:end/disp8 - # *eax = 0 - c6 0/subop/copy-byte *eax 0/imm8 - # ++eax - 40/increment-eax - eb/jump $clear-stack:loop/disp8 -$clear-stack:end: - # . restore registers - 59/pop-to-ecx - 58/pop-to-eax - # . epilog - 89/<- %esp 5/r32/ebp - 5d/pop-to-ebp - c3/return - -test-clear-stack: - # var ecx : (address stack) = stack of size 8 with random data in it - 68/push 34/imm32 - 68/push 35/imm32 - 68/push 8/imm32/length - 68/push 14/imm32/top - 89/<- %ecx 4/r32/esp - # clear - (clear-stack %ecx) - # top should be 0 - 58/pop-to-eax - (check-ints-equal %eax 0 "F - test-clear-stack: top") - # length should remain 8 - 58/pop-to-eax - (check-ints-equal %eax 8 "F - test-clear-stack: length") - # first word is 0 - 58/pop-to-eax - (check-ints-equal %eax 0 "F - test-clear-stack: data[0..3]") - # second word is 0 - 58/pop-to-eax - (check-ints-equal %eax 0 "F - test-clear-stack: data[4..7]") - c3/return - -push: # s : (address stack), n : int - # . prolog - 55/push-ebp - 89/<- %ebp 4/r32/esp - # . save registers - 50/push-eax - 51/push-ecx - 56/push-esi - # esi = s - 8b/-> *(ebp+8) 6/r32/esi - # ecx = s->top - 8b/-> *esi 1/r32/ecx - # if (s->top >= s->length) abort - 39/compare *(esi+4) 1/r32/ecx - 7e/jump-if-lesser-or-equal $push:abort/disp8 - # s->data[s->top] = n - 8b/-> *(ebp+0xc) 0/r32/eax - 89/<- *(esi+ecx+8) 0/r32/eax - # s->top += 4 - 81 0/subop/add *esi 4/imm32 -$push:end: - # . restore registers - 5e/pop-to-esi - 59/pop-to-ecx - 58/pop-to-eax - # . epilog - 89/<- %esp 5/r32/ebp - 5d/pop-to-ebp - c3/return - -$push:abort: - # print(stderr, "error: push: no space left") - # . write-buffered(Stderr, "error: push: no space left") - # . . push args - 68/push "error: push: no space left"/imm32 - 68/push Stderr/imm32 - # . . call - e8/call write-buffered/disp32 - # . . discard args - 81 0/subop/add %esp 8/imm32 - # . flush(Stderr) - # . . push args - 68/push Stderr/imm32 - # . . call - e8/call flush/disp32 - # . . discard args - 81 0/subop/add %esp 4/imm32 - # . syscall(exit, 1) - bb/copy-to-ebx 1/imm32 - b8/copy-to-eax 1/imm32/exit - cd/syscall 0x80/imm8 - # never gets here - -test-push: - # var ecx : (address stack) = empty stack of size 8 - 68/push 0/imm32 - 68/push 0/imm32 - 68/push 8/imm32/length - 68/push 0/imm32/top - 89/<- %ecx 4/r32/esp - # - (push %ecx 42) - # top - 58/pop-to-eax - (check-ints-equal %eax 4 "F - test-push: top") - # length - 58/pop-to-eax - (check-ints-equal %eax 8 "F - test-push: length") - # first word is 42 - 58/pop-to-eax - (check-ints-equal %eax 42 "F - test-push: data[0..3]") - # second word is 0 - 58/pop-to-eax - (check-ints-equal %eax 0 "F - test-push: data[4..7]") - c3/return - -pop: # s : (address stack) -> n/eax : int - # . prolog - 55/push-ebp - 89/<- %ebp 4/r32/esp - # . save registers - 51/push-ecx - 56/push-esi - # esi = s - 8b/-> *(ebp+8) 6/r32/esi - # if (s->top <= 0) abort - 81 7/subop/compare *esi 0/imm32 - 7e/jump-if-lesser-or-equal $pop:abort/disp8 - # s->top -= 4 - 81 5/subop/subtract *esi 4/imm32 - # eax = s->data[s->top] - 8b/-> *esi 1/r32/ecx/top - 8b/-> *(esi+ecx+8) 0/r32/eax -$pop:end: - # . restore registers - 5e/pop-to-esi - 59/pop-to-ecx - # . epilog - 89/<- %esp 5/r32/ebp - 5d/pop-to-ebp - c3/return - -$pop:abort: - # print(stderr, "error: pop: nothing left in stack") - # . write-buffered(Stderr, "error: pop: nothing left in stack") - # . . push args - 68/push "error: pop: nothing left in stack"/imm32 - 68/push Stderr/imm32 - # . . call - e8/call write-buffered/disp32 - # . . discard args - 81 0/subop/add %esp 8/imm32 - # . flush(Stderr) - # . . push args - 68/push Stderr/imm32 - # . . call - e8/call flush/disp32 - # . . discard args - 81 0/subop/add %esp 4/imm32 - # . syscall(exit, 1) - bb/copy-to-ebx 1/imm32 - b8/copy-to-eax 1/imm32/exit - cd/syscall 0x80/imm8 - # never gets here - -test-pop: - # var ecx : (address stack) = stack of size 8 containing just 42 - 68/push 0/imm32 - 68/push 42/imm32 - 68/push 8/imm32/length - 68/push 4/imm32/top - 89/<- %ecx 4/r32/esp - # - (pop %ecx) # => eax - # result - (check-ints-equal %eax 42 "F - test-pop: result") - # top - 58/pop-to-eax - (check-ints-equal %eax 0 "F - test-pop: top") - # length - 58/pop-to-eax - (check-ints-equal %eax 8 "F - test-pop: length") - # clean up - 81 0/subop/add %esp 8/imm32 - c3/return - -top: # s : (address stack) -> n/eax : int - # . prolog - 55/push-ebp - 89/<- %ebp 4/r32/esp - # . save registers - 51/push-ecx - 56/push-esi - # esi = s - 8b/-> *(ebp+8) 6/r32/esi - # if (s->top <= 0) abort - 81 7/subop/compare *esi 0/imm32 - 7e/jump-if-lesser-or-equal $top:abort/disp8 - # eax = s->data[s->top - 4] - 8b/-> *esi 1/r32/ecx/top - 81 5/subop/subtract %ecx 4/imm32 - 8b/-> *(esi+ecx+8) 0/r32/eax -$top:end: - # . restore registers - 5e/pop-to-esi - 59/pop-to-ecx - # . epilog - 89/<- %esp 5/r32/ebp - 5d/pop-to-ebp - c3/return - -$top:abort: - # print(stderr, "error: top: nothing left in stack") - # . write-buffered(Stderr, "error: top: nothing left in stack") - # . . push args - 68/push "error: top: nothing left in stack"/imm32 - 68/push Stderr/imm32 - # . . call - e8/call write-buffered/disp32 - # . . discard args - 81 0/subop/add %esp 8/imm32 - # . flush(Stderr) - # . . push args - 68/push Stderr/imm32 - # . . call - e8/call flush/disp32 - # . . discard args - 81 0/subop/add %esp 4/imm32 - # . syscall(exit, 1) - bb/copy-to-ebx 1/imm32 - b8/copy-to-eax 1/imm32/exit - cd/syscall 0x80/imm8 - # never gets here - -test-top: - # var ecx : (address stack) = stack of size 8 containing just 42 - 68/push 0/imm32 - 68/push 42/imm32 - 68/push 8/imm32/length - 68/push 4/imm32/top - 89/<- %ecx 4/r32/esp - # - (top %ecx) # => eax - # result - (check-ints-equal %eax 42 "F - test-top: result") - # clean up - 81 0/subop/add %esp 0x10/imm32 - c3/return -- cgit 1.4.1-2-gfad0