mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-01 04:10:18 +02:00
* dynwind.c: #include "genio.h"; #include "smob.h"; Implemented a
new data type (guards) for representation of C level guards and data on the wind chain. (scm_internal_dynamic_wind): New function. * dynwind.h: Declare scm_internal_dynamic_wind. * load.c: #include "dynwind.h"; (scm_primitive_load): Use scm_inner_dynamic_wind to update scm_cur_loadp.
This commit is contained in:
parent
ef0d04e5c3
commit
3346a90fa7
2 changed files with 82 additions and 0 deletions
|
@ -45,6 +45,8 @@
|
||||||
#include "eval.h"
|
#include "eval.h"
|
||||||
#include "alist.h"
|
#include "alist.h"
|
||||||
#include "fluids.h"
|
#include "fluids.h"
|
||||||
|
#include "genio.h"
|
||||||
|
#include "smob.h"
|
||||||
|
|
||||||
#include "dynwind.h"
|
#include "dynwind.h"
|
||||||
|
|
||||||
|
@ -81,6 +83,73 @@ scm_dynamic_wind (thunk1, thunk2, thunk3)
|
||||||
return ans;
|
return ans;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The implementation of a C-callable dynamic-wind,
|
||||||
|
* scm_internal_dynamic_wind, requires packaging of C pointers in a
|
||||||
|
* smob. Objects of this type are pushed onto the dynwind chain.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct guardsmem {
|
||||||
|
scm_guard_t before;
|
||||||
|
scm_guard_t after;
|
||||||
|
void *data;
|
||||||
|
} guardsmem;
|
||||||
|
|
||||||
|
#define SCM_GUARDSMEM(obj) ((guardsmem *) SCM_CDR (obj))
|
||||||
|
#define SCM_BEFORE_GUARD(obj) (SCM_GUARDSMEM (obj)->before)
|
||||||
|
#define SCM_AFTER_GUARD(obj) (SCM_GUARDSMEM (obj)->after)
|
||||||
|
#define SCM_GUARD_DATA(obj) (SCM_GUARDSMEM (obj)->data)
|
||||||
|
#define SCM_GUARDSP(obj) (SCM_CAR (obj) == tc16_guards)
|
||||||
|
|
||||||
|
static long tc16_guards;
|
||||||
|
|
||||||
|
static scm_sizet
|
||||||
|
freeguards (SCM guards)
|
||||||
|
{
|
||||||
|
scm_must_free ((char *) SCM_CDR (guards));
|
||||||
|
return sizeof (guardsmem);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
printguards (SCM exp, SCM port, scm_print_state *pstate)
|
||||||
|
{
|
||||||
|
scm_puts ("#<guards ", port);
|
||||||
|
scm_intprint (SCM_CDR (exp), 16, port);
|
||||||
|
scm_putc ('>', port);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static scm_smobfuns guardsmob = {
|
||||||
|
scm_mark0,
|
||||||
|
freeguards,
|
||||||
|
printguards,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
SCM
|
||||||
|
scm_internal_dynamic_wind (scm_guard_t before,
|
||||||
|
scm_inner_t inner,
|
||||||
|
scm_guard_t after,
|
||||||
|
void *inner_data,
|
||||||
|
void *guard_data)
|
||||||
|
{
|
||||||
|
SCM guards, ans;
|
||||||
|
guardsmem *g;
|
||||||
|
before (guard_data);
|
||||||
|
SCM_NEWCELL (guards);
|
||||||
|
SCM_DEFER_INTS;
|
||||||
|
g = (guardsmem *) scm_must_malloc (sizeof (*g), "guards");
|
||||||
|
g->before = before;
|
||||||
|
g->after = after;
|
||||||
|
g->data = guard_data;
|
||||||
|
SCM_SETCDR (guards, g);
|
||||||
|
SCM_SETCAR (guards, tc16_guards);
|
||||||
|
SCM_ALLOW_INTS;
|
||||||
|
scm_dynwinds = scm_acons (guards, SCM_BOOL_F, scm_dynwinds);
|
||||||
|
ans = inner (inner_data);
|
||||||
|
scm_dynwinds = SCM_CDR (scm_dynwinds);
|
||||||
|
after (guard_data);
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef GUILE_DEBUG
|
#ifdef GUILE_DEBUG
|
||||||
SCM_PROC (s_wind_chain, "wind-chain", 0, 0, 0, scm_wind_chain);
|
SCM_PROC (s_wind_chain, "wind-chain", 0, 0, 0, scm_wind_chain);
|
||||||
|
@ -122,6 +191,8 @@ scm_dowinds (to, delta)
|
||||||
{
|
{
|
||||||
if (SCM_NIMP (wind_key) && SCM_CONSP (wind_key))
|
if (SCM_NIMP (wind_key) && SCM_CONSP (wind_key))
|
||||||
scm_swap_fluids (wind_key, SCM_CDR (wind_elt));
|
scm_swap_fluids (wind_key, SCM_CDR (wind_elt));
|
||||||
|
else if (SCM_NIMP (wind_key) && SCM_GUARDSP (wind_key))
|
||||||
|
SCM_BEFORE_GUARD (wind_key) (SCM_GUARD_DATA (wind_key));
|
||||||
else
|
else
|
||||||
scm_apply (wind_key, SCM_EOL, SCM_EOL);
|
scm_apply (wind_key, SCM_EOL, SCM_EOL);
|
||||||
}
|
}
|
||||||
|
@ -152,6 +223,8 @@ scm_dowinds (to, delta)
|
||||||
{
|
{
|
||||||
if (SCM_NIMP (wind_key) && SCM_CONSP (wind_key))
|
if (SCM_NIMP (wind_key) && SCM_CONSP (wind_key))
|
||||||
scm_swap_fluids_reverse (wind_key, from);
|
scm_swap_fluids_reverse (wind_key, from);
|
||||||
|
else if (SCM_NIMP (wind_key) && SCM_GUARDSP (wind_key))
|
||||||
|
SCM_AFTER_GUARD (wind_key) (SCM_GUARD_DATA (wind_key));
|
||||||
else
|
else
|
||||||
scm_apply (from, SCM_EOL, SCM_EOL);
|
scm_apply (from, SCM_EOL, SCM_EOL);
|
||||||
}
|
}
|
||||||
|
@ -166,5 +239,6 @@ scm_dowinds (to, delta)
|
||||||
void
|
void
|
||||||
scm_init_dynwind ()
|
scm_init_dynwind ()
|
||||||
{
|
{
|
||||||
|
tc16_guards = scm_newsmob (&guardsmob);
|
||||||
#include "dynwind.x"
|
#include "dynwind.x"
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,15 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef void (*scm_guard_t) (void *);
|
||||||
|
typedef SCM (*scm_inner_t) (void *);
|
||||||
|
|
||||||
extern SCM scm_dynamic_wind SCM_P ((SCM thunk1, SCM thunk2, SCM thunk3));
|
extern SCM scm_dynamic_wind SCM_P ((SCM thunk1, SCM thunk2, SCM thunk3));
|
||||||
|
extern SCM scm_internal_dynamic_wind SCM_P ((scm_guard_t before,
|
||||||
|
scm_inner_t inner,
|
||||||
|
scm_guard_t after,
|
||||||
|
void *inner_data,
|
||||||
|
void *guard_data));
|
||||||
extern void scm_dowinds SCM_P ((SCM to, long delta));
|
extern void scm_dowinds SCM_P ((SCM to, long delta));
|
||||||
extern void scm_init_dynwind SCM_P ((void));
|
extern void scm_init_dynwind SCM_P ((void));
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue