Implement new procedure `dstack_alloc_and_protect' that combines
authorChris Hanson <org/chris-hanson/cph>
Fri, 5 Jul 1991 23:28:57 +0000 (23:28 +0000)
committerChris Hanson <org/chris-hanson/cph>
Fri, 5 Jul 1991 23:28:57 +0000 (23:28 +0000)
`dstack_alloc' and `dstack_protect', saving space and improving
atomicity.  Eliminate CATCH and THROW macros.

v7/src/microcode/dstack.h
v7/src/microcode/wind.c

index e29d13649c2290b7d2f1fee8e87e499118df9706..7899997969aa48521110d0975f84e4ca93f6ffe9 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1990 Free Software Foundation, Inc.
+/* Copyright (C) 1990-91 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -14,7 +14,7 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
-/* $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/microcode/dstack.h,v 1.1 1990/06/20 19:35:44 cph Rel $ */
+/* $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/microcode/dstack.h,v 1.2 1991/07/05 23:28:40 cph Exp $ */
 
 #ifndef __DSTACK_H__
 #define __DSTACK_H__
@@ -35,10 +35,19 @@ extern PTR EXFUN (dstack_alloc, (unsigned int length));
 extern void EXFUN
   (dstack_protect,
    (void EXFUN ((*protector), (PTR environment)), PTR environment));
-/* Create an unwind protection frame which invokes `protector' when
+/* Create an unwind protection frame that invokes `protector' when
    the stack is unwound.  `environment' is passed to `protector' as
    its sole argument when it is invoked. */
 
+extern void EXFUN
+  (dstack_alloc_and_protect,
+   (unsigned int length,
+    void EXFUN ((*initializer), (PTR environment)),
+    void EXFUN ((*protector), (PTR environment))));
+/* Allocate a chunk of `length' bytes of space, call `initializer' to
+   initialize that space, and create an unwind protection frame that
+   invokes `protector' when the stack is unwound.  */
+
 extern PTR dstack_position;
 /* The current stack pointer. */
 
@@ -46,27 +55,6 @@ extern void EXFUN (dstack_set_position, (PTR position));
 /* Unwind the stack to `position', which must be a previous value of
    `dstack_position'. */
 
-typedef struct
-{
-  PTR stack_pointer;
-  jmp_buf env;
-} Tcatch_tag;
-
-#define CATCH(tag)                                                     \
-  ((((tag) . stack_pointer) = dstack_position),                                \
-   (setjmp ((tag) . env)))
-
-#define THROW(tag, value)                                              \
-{                                                                      \
-  /* Copy `tag' in case it is dstack-allocated. */                     \
-  /* Must split declaration and assignment because some compilers      \
-     do not permit aggregate initializers. */                          \
-  Tcatch_tag THROW_tag;                                                        \
-  THROW_tag = (tag);                                                   \
-  dstack_set_position (THROW_tag . stack_pointer);                     \
-  longjmp ((THROW_tag . env), (value));                                        \
-}
-
 extern void EXFUN (dstack_bind, (PTR location, PTR value));
 /* Dynamically bind `location' to `value'.  `location' is treated as
    `PTR*' -- it is declared `PTR' for programming convenience. */
index f5ef116aae4f2d652601eee8908dff5a94208556..3c71f7826942d54ce3332443625ef3b2fc677c24 100644 (file)
@@ -14,7 +14,7 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
-/* $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/microcode/wind.c,v 1.2 1991/07/02 18:16:59 cph Exp $ */
+/* $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/microcode/wind.c,v 1.3 1991/07/05 23:28:57 cph Exp $ */
 
 #include <stdio.h>
 #include "obstack.h"
@@ -101,6 +101,22 @@ DEFUN (dstack_protect, (protector, environment),
   current_winding_record = record;
 }
 
+void
+DEFUN (dstack_alloc_and_protect, (length, initializer, protector),
+       unsigned int length AND
+       void EXFUN ((*initializer), (PTR environment)) AND
+       void EXFUN ((*protector), (PTR environment)))
+{
+  struct winding_record * record =
+    (dstack_alloc ((sizeof (struct winding_record)) + length));
+  PTR environment = (((char *) record) + (sizeof (struct winding_record)));
+  (*initializer) (environment);
+  (record -> next) = current_winding_record;
+  (record -> protector) = protector;
+  (record -> environment) = environment;
+  current_winding_record = record;
+}
+
 void
 DEFUN (dstack_set_position, (position), PTR position)
 {
@@ -146,19 +162,28 @@ struct binding_record
 };
 
 static void
-DEFUN (undo_binding, (record), PTR record)
+DEFUN (undo_binding, (environment), PTR environment)
+{
+  (* (((struct binding_record *) environment) -> location)) =
+    (((struct binding_record *) environment) -> value);
+}
+
+static PTR * save_binding_location;
+
+static void
+DEFUN (save_binding, (environment), PTR environment)
 {
-  (* (((struct binding_record *) record) -> location)) =
-    (((struct binding_record *) record) -> value);
+  (((struct binding_record *) environment) -> location) =
+    save_binding_location;
+  (((struct binding_record *) environment) -> value) =
+    (*save_binding_location);
 }
 
 void
 DEFUN (dstack_bind, (location, value), PTR location AND PTR value)
 {
-  struct binding_record * record =
-    (dstack_alloc (sizeof (struct binding_record)));
-  (record -> location) = ((PTR *) location);
-  (record -> value) = (* ((PTR *) location));
-  dstack_protect (undo_binding, record);
+  save_binding_location = location;
+  dstack_alloc_and_protect
+    ((sizeof (struct binding_record)), save_binding, undo_binding);
   (* ((PTR *) location)) = value;
 }