mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 03:40:34 +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 "alist.h"
|
||||
#include "fluids.h"
|
||||
#include "genio.h"
|
||||
#include "smob.h"
|
||||
|
||||
#include "dynwind.h"
|
||||
|
||||
|
@ -81,6 +83,73 @@ scm_dynamic_wind (thunk1, thunk2, thunk3)
|
|||
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
|
||||
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))
|
||||
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
|
||||
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))
|
||||
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
|
||||
scm_apply (from, SCM_EOL, SCM_EOL);
|
||||
}
|
||||
|
@ -166,5 +239,6 @@ scm_dowinds (to, delta)
|
|||
void
|
||||
scm_init_dynwind ()
|
||||
{
|
||||
tc16_guards = scm_newsmob (&guardsmob);
|
||||
#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_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_init_dynwind SCM_P ((void));
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue