about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAnselm R. Garbe <arg@10kloc.org>2006-09-29 14:39:03 +0200
committerAnselm R. Garbe <arg@10kloc.org>2006-09-29 14:39:03 +0200
commit8fa47ac679cfd91c022a35f2469bea7396e5f7c7 (patch)
treec8b37c825579621dd058e5a4b49dc1a77ae4e97c
parentb427a2c6cb9c221075e42d0d1007e980a949a7df (diff)
downloaddwm-8fa47ac679cfd91c022a35f2469bea7396e5f7c7.tar.gz
prelim of dotile()
-rw-r--r--dwm.h1
-rw-r--r--view.c104
2 files changed, 68 insertions, 37 deletions
diff --git a/dwm.h b/dwm.h
index 0d2ed3f..ead92b3 100644
--- a/dwm.h
+++ b/dwm.h
@@ -40,6 +40,7 @@
 #define MOUSEMASK		(BUTTONMASK | PointerMotionMask)
 /* other stuff used in different places */
 #define BORDERPX		1
+#define MINW			100
 #define PROTODELWIN		1
 
 enum { NetSupported, NetWMName, NetLast };		/* EWMH atoms */
diff --git a/view.c b/view.c
index 90080fb..b2ee32f 100644
--- a/view.c
+++ b/view.c
@@ -99,36 +99,39 @@ dofloat(Arg *arg) {
 
 /* This algorithm is based on a (M)aster area and a (S)tacking area.
  * It supports following arrangements:
- * 	MMMS		MMMM		SMMM
- * 	MMMS		MMMM		SMMM
- * 	MMMS		SSSS		SMMM
+ * 	SSMMM	MMMMM	MMMSS
+ * 	SSMMM	SSSSS	MMMSS
  */
 void
 dotile(Arg *arg) {
-	int h, i, n, w;
+	int i, n, stackw, stackh, tw, th;
 	Client *c;
 
 	for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
 		n++;
 
-	if(isvertical) {
-		if(stackpos == StackBottom) {
-			w = sw;
-			if(n > 1)
-				h = (sh - bh) / (n - 1);
-			else
-				h = sh - bh;
-		}
-		else {
-			w = sw - master;
-			if(n > 1)
-				h = (sh - bh) / (n - 1);
-			else
-				h = sh - bh;
-		}
+	if(stackpos == StackBottom) {
+		stackw = sw;
+		stackh = sh - bh - master;
+	}
+	else {
+		stackw = sw - master;
+		stackh = sh - bh;
 	}
-	else { /* horizontal stack */
 
+	if(isvertical) {
+		tw = stackw;
+		if(n > 1)
+			th = stackh / (n - 1);
+		else
+			th = stackh;
+	}
+	else {
+		th = stackh;
+		if(n > 1)
+			tw = stackw / (n - 1);
+		else
+			tw = stackw;
 	}
 
 	for(i = 0, c = clients; c; c = c->next) {
@@ -138,32 +141,59 @@ dotile(Arg *arg) {
 				continue;
 			}
 			c->ismax = False;
-			if(n == 1) {
+			if(n == 1) { /* only 1 window */
 				c->x = sx;
 				c->y = sy + bh;
 				c->w = sw - 2 * BORDERPX;
 				c->h = sh - 2 * BORDERPX - bh;
 			}
-			else if(i == 0) {
+			else if(i == 0) { /* master window */
 				c->x = sx;
+				if(stackpos == StackLeft)
+					c->x += master;
 				c->y = sy + bh;
-				c->w = master - 2 * BORDERPX;
-				c->h = sh - 2 * BORDERPX - bh;
+				if(isvertical) {
+					c->w = master - 2 * BORDERPX;
+					c->h = sh - 2 * BORDERPX - bh;
+				}
+				else {
+					c->w = sw;
+					c->h = master - 2 * BORDERPX;
+				}
 			}
-			else if(h > bh) {
-				c->x = sx + master;
-				c->y = sy + (i - 1) * h + bh;
-				c->w = w - 2 * BORDERPX;
-				if(i + 1 == n)
-					c->h = sh - c->y - 2 * BORDERPX;
+			else if((isvertical && th > bh) || (!isvertical && tw > MINW)) {
+				/* tile window */
+				c->x = sx;
+				if(isvertical)
+					c->y = sy + (i - 1) * th + bh;
 				else
-					c->h = h - 2 * BORDERPX;
+					c->y = sy + bh;
+				if(stackpos == StackRight)
+					c->x += master;
+				else if(stackpos == StackBottom)
+					c->y += master;
+				c->w = tw - 2 * BORDERPX;
+				c->h = th - 2 * BORDERPX;
+				if(i + 1 == n) { /* fixes for last tile to take up rest space */
+					if(isvertical)
+						c->h = sh - c->y - 2 * BORDERPX;
+					else {
+						if(stackpos == StackLeft)
+							c->w = master - c->x - 2 * BORDERPX;
+						else
+							c->w = sw - c->x - 2 * BORDERPX;
+					}
+				}
 			}
-			else { /* fallback if h < bh */
-				c->x = sx + master;
+			else { /* fallback if th < bh resp. tw < MINW */
+				c->x = sx;
 				c->y = sy + bh;
-				c->w = w - 2 * BORDERPX;
-				c->h = sh - 2 * BORDERPX - bh;
+				if(stackpos == StackRight)
+					c->x += master;
+				else if(stackpos == StackBottom)
+					c->y += master;
+				c->w = stackw - 2 * BORDERPX;
+				c->h = stackh - 2 * BORDERPX;
 			}
 			resize(c, False, TopLeft);
 			i++;
@@ -232,12 +262,12 @@ resizecol(Arg *arg) {
 		return;
 
 	if(sel == getnext(clients)) {
-		if(master + arg->i > sw - 100 || master + arg->i < 100)
+		if(master + arg->i > sw - MINW || master + arg->i < MINW)
 			return;
 		master += arg->i;
 	}
 	else {
-		if(master - arg->i > sw - 100 || master - arg->i < 100)
+		if(master - arg->i > sw - MINW || master - arg->i < MINW)
 			return;
 		master -= arg->i;
 	}
href='#n358'>358 359 360 361
# A sketch of Mu-style handles or kinda-safe pointers, that add a modicum of
# checking to dynamically allocated memory.
#
# This approach avoids using 'allocate' directly in favor of two primitives:
#   - 'new', which allocates some space (the 'payload'), stores the address
#     along with an opaque 'alloc id' in a 'handle', and prepends the same
#     alloc id to the payload.
#   - 'lookup', which checks that the alloc id at the start of a handle matches
#     the alloc id at the start of the payload before returning the address.
#
# Layout of a handle:
#   offset 0: alloc id
#   offset 4: address
#
# To run (from the subx directory):
#   $ ./subx translate *.subx apps/handle.subx -o apps/handle
#   $ ./subx run apps/handle
# Expected result is a hard abort:
#   ........lookup failed
# (This file is a prototype, so the tests in this file aren't real tests. Don't
# expect to run anything in the same process after they've completed.)

== code
#   instruction                     effective address                                                   register    displacement    immediate
# . op          subop               mod             rm32          base        index         scale       r32
# . 1-3 bytes   3 bits              2 bits          3 bits        3 bits      3 bits        2 bits      2 bits      0/1/2/4 bytes   0/1/2/4 bytes

# main:
    e8/call  run-tests/disp32  # 'run-tests' is a function created automatically by SubX. It calls all functions that start with 'test-'.
    # syscall(exit, Num-test-failures)
    8b/copy                         0/mod/indirect  5/rm32/.disp32            .             .           3/r32/EBX   Num-test-failures/disp32          # copy *Num-test-failures to EBX
    b8/copy-to-EAX  1/imm32/exit
    cd/syscall  0x80/imm8

new:  # ad : (address allocation-descriptor), n : int, out : (address handle)
    # . prolog
    55/push-EBP
    89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
    # . save registers
    50/push-EAX
    51/push-ECX
    52/push-EDX
    # ECX = n+4
    8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .             .           1/r32/ECX   0xc/disp8       .                 # copy *(EBP+12) to ECX
    81          0/subop/add         3/mod/direct    1/rm32/ECX    .           .             .           .           .               4/imm32           # add to ECX
    # EAX = allocate(ad, ECX)
    # . . push args
    51/push-ECX
    ff          6/subop/push        1/mod/*+disp8   5/rm32/EBP    .           .             .           .           8/disp8         .                 # push *(EBP+8)
    # . . call
    e8/call  allocate/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
    # EDX = out
    8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .             .           2/r32/EDX   0x10/disp8      .                 # copy *(EBP+16) to EDX
    # out->address = EAX
    89/copy                         1/mod/*+disp8   2/rm32/EDX    .           .             .           0/r32/EAX   4/disp8         .                 # copy EAX to *(EDX+4)
    # if (EAX == 0) out->alloc_id = 0, return
    81          7/subop/compare     3/mod/direct    0/rm32/EAX    .           .             .           .           .               0/imm32           # compare EAX
    75/jump-if-not-equal  $new:continue/disp8
    c7          0/subop/copy        0/mod/indirect  2/rm32/EDX    .           .             .           .           .               0/imm32           # copy to *EDX
    eb/jump  $new:end/disp8
$new:continue:
    # otherwise:
    # ECX = *Next-alloc-id
    8b/copy                         0/mod/indirect  5/rm32/.disp32            .             .           1/r32/ECX   Next-alloc-id/disp32              # copy *Next-alloc-id to ECX
    # *EAX = *Next-alloc-id/ECX
    89/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy ECX to *EAX
    # out->alloc_id = *Next-alloc-id
    89/copy                         0/mod/indirect  2/rm32/EDX    .           .             .           1/r32/ECX   .               .                 # copy ECX to *EDX
    # increment *Next-alloc-id
    ff          0/subop/increment   0/mod/indirect  5/rm32/.disp32            .             .           .           Next-alloc-id/disp32              # increment *Next-alloc-id
$new:end:
    # . restore registers
    5a/pop-to-EDX
    59/pop-to-ECX
    58/pop-to-EAX
    # . epilog
    89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
    5d/pop-to-EBP
    c3/return

test-new:
    # . prolog
    55/push-EBP
    89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
    # *Next-alloc-id = 0x34
    c7          0/subop/copy        0/mod/indirect  5/rm32/.disp32            .             .           .     Next-alloc-id/disp32  0x34/imm32        # copy to *Next-alloc-id
    # var handle/ECX = {0, 0}
    68/push  0/imm32/address
    68/push  0/imm32/alloc-id
    89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
    # new(Heap, 2, handle/ECX)
    # . . push args
    51/push-ECX
    68/push  2/imm32/size
    68/push  Heap/imm32
    # . . call
    e8/call  new/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
    # check-ints-equal(handle->alloc_id, 0x34, msg)
    # . . push args
    68/push  "F - test-new: alloc id of handle"/imm32
    68/push  0x34/imm32
    ff          6/subop/push        0/mod/indirect  1/rm32/ECX    .           .             .           .           .               .                 # push *ECX
    # . . call
    e8/call  check-ints-equal/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
    # check-ints-equal(*handle->address, 0x34, msg)
    # . . push args
    68/push  "F - test-new: alloc id of payload"/imm32
    68/push  0x34/imm32
    8b/copy                         1/mod/*+disp8   1/rm32/ECX    .           .             .           2/r32/EDX   4/disp8         .                 # copy *(ECX+4) to EDX
    ff          6/subop/push        0/mod/indirect  2/rm32/EDX    .           .             .           .           .               .                 # push *EDX
    # . . call
    e8/call  check-ints-equal/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
    # check-ints-equal(*Next-alloc-id, 0x35)
    # . . push args
    68/push  "F - test-new: next alloc id"/imm32
    68/push  0x35/imm32
    ff          6/subop/push        0/mod/indirect  5/rm32/.disp32            .             .           .           Next-alloc-id/disp32              # copy to *Next-alloc-id
    # . . call
    e8/call  check-ints-equal/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
    # clean up
    # . *Next-alloc-id = 1
    c7          0/subop/copy        0/mod/indirect  5/rm32/.disp32            .             .           .     Next-alloc-id/disp32  1/imm32           # copy to *Next-alloc-id
    # . epilog
    89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
    5d/pop-to-EBP
    c3/return

test-new-failure:
    # . prolog
    55/push-EBP
    89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
    # . *Next-alloc-id = 0x34
    c7          0/subop/copy        0/mod/indirect  5/rm32/.disp32            .             .           .           Next-alloc-id/disp32  0x34/imm32  # copy to *Next-alloc-id
    # define an allocation-descriptor with no space left
    # . var ad/EAX : (address allocation-descriptor) = {0x10, 0x10}
    68/push  0x10/imm32/limit
    68/push  0x10/imm32/curr
    89/copy                         3/mod/direct    0/rm32/EAX    .           .             .           4/r32/ESP   .               .                 # copy ESP to EAX
    # . var handle/ECX = {random, random}
    68/push  1234/imm32/address
    68/push  5678/imm32/alloc-id
    89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
    # try to allocate
    # . new(ad, 2, handle/ECX)
    # . . push args
    51/push-ECX
    68/push  2/imm32/size
    50/push-EAX
    # . . call
    e8/call  new/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
    # handle should be cleared
    # . check-ints-equal(handle->alloc_id, 0, msg)
    # . . push args
    68/push  "F - test-new-failure: alloc id of handle"/imm32
    68/push  0/imm32
    ff          6/subop/push        0/mod/indirect  1/rm32/ECX    .           .             .           .           .               .                 # push *ECX
    # . . call
    e8/call  check-ints-equal/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
    # . check-ints-equal(handle->address, 0, msg)
    # . . push args
    68/push  "F - test-new-failure: address of handle"/imm32
    68/push  0/imm32
    ff          6/subop/push        1/mod/*+disp8   1/rm32/ECX    .           .             .           .           4/disp8         .                 # push *(ECX+4)
    # . . call
    e8/call  check-ints-equal/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
    # Next-alloc-id should be unmodified
    # . check-ints-equal(*Next-alloc-id, 0x34)
    # . . push args
    68/push  "F - test-new-failure: next alloc id"/imm32
    68/push  0x34/imm32
    ff          6/subop/push        0/mod/indirect  5/rm32/.disp32            .             .           .           Next-alloc-id/disp32              # copy to *Next-alloc-id
    # . . call
    e8/call  check-ints-equal/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
    # clean up
    # . *Next-alloc-id = 1
    c7          0/subop/copy        0/mod/indirect  5/rm32/.disp32            .             .           .     Next-alloc-id/disp32  1/imm32           # copy to *Next-alloc-id
    # . epilog
    89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
    5d/pop-to-EBP
    c3/return

lookup:  # h : (handle T) -> EAX : (address T)
    # . prolog
    55/push-EBP
    89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
    # - as a proof of concept for future inlining, uses no general-purpose registers besides the output (EAX)
    # EAX = handle
    8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .             .           0/r32/EAX   8/disp8         .                 # copy *(EBP+8) to EAX
    # - inline {
    # push handle->address
    ff          6/subop/push        1/mod/*+disp8   1/rm32/ECX    .           .             .           .           4/disp8         .                 # push *(EAX+4)
    # EAX = handle->alloc_id
    8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           .           .               .                 # copy *EAX to EAX
    # if (EAX != *ESP) abort
    39/compare                      0/mod/indirect  4/rm32/sib    4/base/ESP  4/index/none  .           0/r32/EAX   .               .                 # compare *ESP and EAX
    75/jump-if-not-equal  $lookup:fail/disp8
    # return ESP+4
    58/pop-to-EAX
    05/add-to-EAX  4/imm32
    # - }
    # . epilog
    89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
    5d/pop-to-EBP
    c3/return
$lookup:fail:
    # . _write(2/stderr, msg)
    # . . push args
    68/push  "lookup failed"/imm32
    68/push  2/imm32/stderr
    # . . call
    e8/call  _write/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
    # . syscall(exit, 1)
    bb/copy-to-EBX  1/imm32/exit-status
    b8/copy-to-EAX  1/imm32/exit
    cd/syscall  0x80/imm8

test-lookup-success:
    # . prolog
    55/push-EBP
    89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
    # . save registers
    # var handle/ECX = {0, 0}
    68/push  0/imm32/address
    68/push  0/imm32/alloc-id
    89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
    # var old_top/EDX = Heap->curr
    8b/copy                         0/mod/indirect  5/rm32/.disp32            .             .           2/r32/EDX   Heap/disp32     .                 # copy *Heap to EDX
    # new(Heap, 2, handle)
    # . . push args
    51/push-ECX
    68/push  2/imm32/size
    68/push  Heap/imm32
    # . . call
    e8/call  new/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
    # EAX = lookup(handle)
    # . . push args
    51/push-ECX
    # . . call
    e8/call  lookup/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
    # EAX contains old top of Heap, except skipping the alloc id in the payload
    # . check-ints-equal(EAX, old_top+4, msg)
    # . . push args
    68/push  "F - test-lookup-success"/imm32
    81          0/subop/add         3/mod/direct    2/rm32/EDX    .           .             .           .           .               4/imm32           # add to EDX
    52/push-EDX
    50/push-EAX
    # . . call
    e8/call  check-ints-equal/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
    # clean up
    # . *Next-alloc-id = 1
    c7          0/subop/copy        0/mod/indirect  5/rm32/.disp32            .             .           .     Next-alloc-id/disp32  1/imm32           # copy to *Next-alloc-id
    # . restore registers
    5a/pop-to-EDX
    59/pop-to-ECX
    # . epilog
    89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
    5d/pop-to-EBP
    c3/return

test-lookup-failure:
    # . prolog
    55/push-EBP
    89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
    # . save registers
    50/push-EAX
    51/push-ECX
    52/push-EDX
    # var h1/ECX = {0, 0}
    68/push  0/imm32/address
    68/push  0/imm32/alloc-id
    89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
    # var old_top/EBX = Heap->curr
    8b/copy                         0/mod/indirect  5/rm32/.disp32            .             .           3/r32/EBX   Heap/disp32     .                 # copy *Heap to EBX
    # first allocation, to h1
    # . new(Heap, 2, h1)
    # . . push args
    51/push-ECX
    68/push  2/imm32/size
    68/push  Heap/imm32
    # . . call
    e8/call  new/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
    # reset Heap->curr to mimic reclamation
    89/copy                         0/mod/indirect  5/rm32/.disp32            .             .           3/r32/EBX   Heap/disp32     .                 # copy EBX to *Heap
    # second allocation that returns the same address as the first
    # var h2/EDX = {0, 0}
    68/push  0/imm32/address
    68/push  0/imm32/alloc-id
    89/copy                         3/mod/direct    2/rm32/EDX    .           .             .           4/r32/ESP   .               .                 # copy ESP to EDX
    # . new(Heap, 2, h2)
    # . . push args
    52/push-EDX
    68/push  2/imm32/size
    68/push  Heap/imm32
    # . . call
    e8/call  new/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
    # check-ints-equal(h1->address, h2->address, msg)
    # . . push args
    68/push  "F - test-lookup-failure"/imm32
    ff          6/subop/push        1/mod/*+disp8   2/rm32/ECX    .           .             .           .           4/disp8         .                 # push *(EDX+4)
    ff          6/subop/push        1/mod/*+disp8   1/rm32/ECX    .           .             .           .           4/disp8         .                 # push *(ECX+4)
    # . . call
    e8/call  check-ints-equal/disp32
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
    # lookup(h1) should crash
    # . . push args
    51/push-ECX
    # . . call
    e8/call  lookup/disp32
    # should never get past this point
    # . . discard args
    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
    # clean up
    # . *Next-alloc-id = 1
    c7          0/subop/copy        0/mod/indirect  5/rm32/.disp32            .             .           .     Next-alloc-id/disp32  1/imm32           # copy to *Next-alloc-id
    # . restore registers
    5a/pop-to-EDX
    59/pop-to-ECX
    58/pop-to-EAX
    # . epilog
    89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
    5d/pop-to-EBP
    c3/return

== data

# Monotonically increasing counter for calls to 'new'
Next-alloc-id:
    1/imm32

# . . vim:nowrap:textwidth=0