From a904e413868f86ababf250ce742b06e287befa7f Mon Sep 17 00:00:00 2001 From: Chris Hanson Date: Fri, 5 Jul 1991 23:28:57 +0000 Subject: [PATCH] Implement new procedure `dstack_alloc_and_protect' that combines `dstack_alloc' and `dstack_protect', saving space and improving atomicity. Eliminate CATCH and THROW macros. --- v7/src/microcode/dstack.h | 36 +++++++++++--------------------- v7/src/microcode/wind.c | 43 +++++++++++++++++++++++++++++++-------- 2 files changed, 46 insertions(+), 33 deletions(-) diff --git a/v7/src/microcode/dstack.h b/v7/src/microcode/dstack.h index e29d13649..789999796 100644 --- a/v7/src/microcode/dstack.h +++ b/v7/src/microcode/dstack.h @@ -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. */ diff --git a/v7/src/microcode/wind.c b/v7/src/microcode/wind.c index f5ef116aa..3c71f7826 100644 --- a/v7/src/microcode/wind.c +++ b/v7/src/microcode/wind.c @@ -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 #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; } -- 2.25.1