1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-04-30 11:50:28 +02:00

Simplify dynstack API to only wind one fluid at a time

* libguile/dynstack.h (SCM_DYNSTACK_TYPE_WITH_FLUID): Rename from
  with-fluids.
* libguile/dynstack.c (scm_dynstack_push_fluid):
  (scm_dynstack_unwind_fluid): Change API to only wind/unwind one
  fluid binding.
  (WITH_FLUID_WORDS): New define, always 2 words (fluid and value box).
  (WITH_FLUID_FLUID, WITH_FLUID_VALUE_BOX): New macros to get offsets of
  fluid and value box.
  (scm_dynstack_push_rewinder, scm_dynstack_push_unwinder): Use
  WINDER_WORDS.
  (scm_dynstack_push_dynwind): Use DYNWIND_WORDS.
  (scm_dynstack_wind_1): Update for scm_swap_fluid API change.

* libguile/fluids.h:
* libguile/fluids.c (scm_prepare_fluids): Remove; no longer needed.
  (scm_swap_fluid): Update to just swap one fluid binding.
  (scm_c_with_fluids, scm_c_with_fluid): Update to use
  scm_dynstack_push_fluid.

* libguile/memoize.c (do_push_fluid, do_pop_fluid): Adapt to API
  change.
* libguile/vm-engine.c (rtl_vm_engine): Change wind-fluids / unwind-fluids
  to push-fluid / pop-fluid, and actually enable.  Woo!

* libguile/vm-i-system.c (push-fluid, pop-fluid): Update to new API.
This commit is contained in:
Andy Wingo 2013-06-28 20:01:35 +02:00
parent c32b7c4cef
commit 98eaef1b50
7 changed files with 85 additions and 150 deletions

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2012 Free Software Foundation, Inc. /* Copyright (C) 2012, 2013 Free Software Foundation, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License * modify it under the terms of the GNU Lesser General Public License
@ -49,8 +49,9 @@
#define DYNWIND_ENTER(top) (SCM_PACK ((top)[0])) #define DYNWIND_ENTER(top) (SCM_PACK ((top)[0]))
#define DYNWIND_LEAVE(top) (SCM_PACK ((top)[1])) #define DYNWIND_LEAVE(top) (SCM_PACK ((top)[1]))
#define WITH_FLUIDS_FLUIDS(top) ((SCM*)((top) + 1)) #define WITH_FLUID_WORDS 2
#define WITH_FLUIDS_VALUES(top) ((SCM*)((top)[0])) #define WITH_FLUID_FLUID(top) (SCM_PACK ((top)[0]))
#define WITH_FLUID_VALUE_BOX(top) (SCM_PACK ((top)[1]))
@ -64,15 +65,6 @@ copy_scm_t_bits (scm_t_bits *dst, scm_t_bits *src, size_t n)
dst[i] = src[i]; dst[i] = src[i];
} }
static void
copy_scm (SCM *dst, SCM *src, size_t n)
{
size_t i;
for (i = 0; i < n; i++)
dst[i] = src[i];
}
static void static void
clear_scm_t_bits (scm_t_bits *items, size_t n) clear_scm_t_bits (scm_t_bits *items, size_t n)
{ {
@ -147,7 +139,8 @@ scm_dynstack_push_rewinder (scm_t_dynstack *dynstack,
{ {
scm_t_bits *words; scm_t_bits *words;
words = push_dynstack_entry (dynstack, SCM_DYNSTACK_TYPE_REWINDER, flags, 2); words = push_dynstack_entry (dynstack, SCM_DYNSTACK_TYPE_REWINDER, flags,
WINDER_WORDS);
words[0] = (scm_t_bits) proc; words[0] = (scm_t_bits) proc;
words[1] = (scm_t_bits) data; words[1] = (scm_t_bits) data;
} }
@ -159,33 +152,34 @@ scm_dynstack_push_unwinder (scm_t_dynstack *dynstack,
{ {
scm_t_bits *words; scm_t_bits *words;
words = push_dynstack_entry (dynstack, SCM_DYNSTACK_TYPE_UNWINDER, flags, 2); words = push_dynstack_entry (dynstack, SCM_DYNSTACK_TYPE_UNWINDER, flags,
WINDER_WORDS);
words[0] = (scm_t_bits) proc; words[0] = (scm_t_bits) proc;
words[1] = (scm_t_bits) data; words[1] = (scm_t_bits) data;
} }
/* The fluids are stored on the stack. However, the values have to be /* The fluid is stored on the stack, but the value has to be stored on the heap,
stored on the heap, so that all continuations that capture this so that all continuations that capture this dynamic scope capture the same
dynamic scope capture the same bindings. */ binding. */
void void
scm_dynstack_push_fluids (scm_t_dynstack *dynstack, size_t n, scm_dynstack_push_fluid (scm_t_dynstack *dynstack, SCM fluid, SCM value,
SCM *fluids, SCM *values, SCM dynamic_state) SCM dynamic_state)
{ {
scm_t_bits *words; scm_t_bits *words;
SCM *heap_values; SCM value_box;
n = scm_prepare_fluids (n, fluids, values); if (SCM_UNLIKELY (!SCM_FLUID_P (fluid)))
heap_values = scm_gc_malloc (n * sizeof (scm_t_bits), "with-fluids"); scm_wrong_type_arg ("with-fluid*", 0, fluid);
copy_scm (heap_values, values, n);
words = push_dynstack_entry (dynstack, SCM_DYNSTACK_TYPE_WITH_FLUIDS, value_box = scm_make_variable (value);
0, n + 1);
words[0] = (scm_t_bits) heap_values; words = push_dynstack_entry (dynstack, SCM_DYNSTACK_TYPE_WITH_FLUID, 0,
copy_scm (WITH_FLUIDS_FLUIDS (words), fluids, n); WITH_FLUID_WORDS);
words[0] = SCM_UNPACK (fluid);
words[1] = SCM_UNPACK (value_box);
/* Go ahead and swap them. */ /* Go ahead and swap them. */
scm_swap_fluids (n, WITH_FLUIDS_FLUIDS (words), WITH_FLUIDS_VALUES (words), scm_swap_fluid (fluid, value_box, dynamic_state);
dynamic_state);
} }
void void
@ -211,7 +205,8 @@ scm_dynstack_push_dynwind (scm_t_dynstack *dynstack, SCM enter, SCM leave)
{ {
scm_t_bits *words; scm_t_bits *words;
words = push_dynstack_entry (dynstack, SCM_DYNSTACK_TYPE_DYNWIND, 0, 2); words = push_dynstack_entry (dynstack, SCM_DYNSTACK_TYPE_DYNWIND, 0,
DYNWIND_WORDS);
words[0] = SCM_UNPACK (enter); words[0] = SCM_UNPACK (enter);
words[1] = SCM_UNPACK (leave); words[1] = SCM_UNPACK (leave);
} }
@ -296,10 +291,10 @@ scm_dynstack_wind_1 (scm_t_dynstack *dynstack, scm_t_bits *item)
WINDER_PROC (item) (WINDER_DATA (item)); WINDER_PROC (item) (WINDER_DATA (item));
break; break;
case SCM_DYNSTACK_TYPE_WITH_FLUIDS: case SCM_DYNSTACK_TYPE_WITH_FLUID:
scm_swap_fluids (len - 1, WITH_FLUIDS_FLUIDS (item), scm_swap_fluid (WITH_FLUID_FLUID (item),
WITH_FLUIDS_VALUES (item), WITH_FLUID_VALUE_BOX (item),
SCM_I_CURRENT_THREAD->dynamic_state); SCM_I_CURRENT_THREAD->dynamic_state);
break; break;
case SCM_DYNSTACK_TYPE_PROMPT: case SCM_DYNSTACK_TYPE_PROMPT:
@ -328,12 +323,10 @@ scm_dynstack_unwind_1 (scm_t_dynstack *dynstack)
scm_t_bits tag; scm_t_bits tag;
scm_t_bits *words; scm_t_bits *words;
scm_t_dynstack_item_type type; scm_t_dynstack_item_type type;
size_t len;
tag = dynstack_pop (dynstack, &words); tag = dynstack_pop (dynstack, &words);
type = SCM_DYNSTACK_TAG_TYPE (tag); type = SCM_DYNSTACK_TAG_TYPE (tag);
len = SCM_DYNSTACK_TAG_LEN (tag);
switch (type) switch (type)
{ {
@ -349,11 +342,11 @@ scm_dynstack_unwind_1 (scm_t_dynstack *dynstack)
clear_scm_t_bits (words, WINDER_WORDS); clear_scm_t_bits (words, WINDER_WORDS);
break; break;
case SCM_DYNSTACK_TYPE_WITH_FLUIDS: case SCM_DYNSTACK_TYPE_WITH_FLUID:
scm_swap_fluids (len - 1, WITH_FLUIDS_FLUIDS (words), scm_swap_fluid (WITH_FLUID_FLUID (words),
WITH_FLUIDS_VALUES (words), WITH_FLUID_VALUE_BOX (words),
SCM_I_CURRENT_THREAD->dynamic_state); SCM_I_CURRENT_THREAD->dynamic_state);
clear_scm_t_bits (words, len); clear_scm_t_bits (words, WITH_FLUID_WORDS);
break; break;
case SCM_DYNSTACK_TYPE_PROMPT: case SCM_DYNSTACK_TYPE_PROMPT:
@ -532,7 +525,7 @@ scm_dynstack_unwind_frame (scm_t_dynstack *dynstack)
/* This function must not allocate. */ /* This function must not allocate. */
void void
scm_dynstack_unwind_fluids (scm_t_dynstack *dynstack, SCM dynamic_state) scm_dynstack_unwind_fluid (scm_t_dynstack *dynstack, SCM dynamic_state)
{ {
scm_t_bits tag, *words; scm_t_bits tag, *words;
size_t len; size_t len;
@ -540,11 +533,11 @@ scm_dynstack_unwind_fluids (scm_t_dynstack *dynstack, SCM dynamic_state)
tag = dynstack_pop (dynstack, &words); tag = dynstack_pop (dynstack, &words);
len = SCM_DYNSTACK_TAG_LEN (tag); len = SCM_DYNSTACK_TAG_LEN (tag);
assert (SCM_DYNSTACK_TAG_TYPE (tag) == SCM_DYNSTACK_TYPE_WITH_FLUIDS); assert (SCM_DYNSTACK_TAG_TYPE (tag) == SCM_DYNSTACK_TYPE_WITH_FLUID);
assert (len >= 1); assert (len == WITH_FLUID_WORDS);
scm_swap_fluids (len - 1, WITH_FLUIDS_FLUIDS (words), scm_swap_fluid (WITH_FLUID_FLUID (words), WITH_FLUID_VALUE_BOX (words),
WITH_FLUIDS_VALUES (words), dynamic_state); dynamic_state);
clear_scm_t_bits (words, len); clear_scm_t_bits (words, len);
} }

View file

@ -3,7 +3,7 @@
#ifndef SCM_DYNSTACK_H #ifndef SCM_DYNSTACK_H
#define SCM_DYNSTACK_H #define SCM_DYNSTACK_H
/* Copyright (C) 2012 Free Software Foundation, Inc. /* Copyright (C) 2012, 2013 Free Software Foundation, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License * modify it under the terms of the GNU Lesser General Public License
@ -79,7 +79,7 @@ typedef enum {
SCM_DYNSTACK_TYPE_FRAME, SCM_DYNSTACK_TYPE_FRAME,
SCM_DYNSTACK_TYPE_UNWINDER, SCM_DYNSTACK_TYPE_UNWINDER,
SCM_DYNSTACK_TYPE_REWINDER, SCM_DYNSTACK_TYPE_REWINDER,
SCM_DYNSTACK_TYPE_WITH_FLUIDS, SCM_DYNSTACK_TYPE_WITH_FLUID,
SCM_DYNSTACK_TYPE_PROMPT, SCM_DYNSTACK_TYPE_PROMPT,
SCM_DYNSTACK_TYPE_DYNWIND, SCM_DYNSTACK_TYPE_DYNWIND,
} scm_t_dynstack_item_type; } scm_t_dynstack_item_type;
@ -148,11 +148,9 @@ SCM_INTERNAL void scm_dynstack_push_rewinder (scm_t_dynstack *,
SCM_INTERNAL void scm_dynstack_push_unwinder (scm_t_dynstack *, SCM_INTERNAL void scm_dynstack_push_unwinder (scm_t_dynstack *,
scm_t_dynstack_winder_flags, scm_t_dynstack_winder_flags,
scm_t_guard, void *); scm_t_guard, void *);
SCM_INTERNAL void scm_dynstack_push_fluids (scm_t_dynstack *, SCM_INTERNAL void scm_dynstack_push_fluid (scm_t_dynstack *,
size_t, SCM fluid, SCM value,
SCM *fluids, SCM dynamic_state);
SCM *values,
SCM dynamic_state);
SCM_INTERNAL void scm_dynstack_push_prompt (scm_t_dynstack *, SCM_INTERNAL void scm_dynstack_push_prompt (scm_t_dynstack *,
scm_t_dynstack_prompt_flags, scm_t_dynstack_prompt_flags,
SCM key, SCM key,
@ -187,8 +185,8 @@ SCM_INTERNAL scm_t_bits* scm_dynstack_unwind_fork (scm_t_dynstack *,
scm_t_dynstack *); scm_t_dynstack *);
SCM_INTERNAL void scm_dynstack_unwind_frame (scm_t_dynstack *); SCM_INTERNAL void scm_dynstack_unwind_frame (scm_t_dynstack *);
SCM_INTERNAL void scm_dynstack_unwind_fluids (scm_t_dynstack *dynstack, SCM_INTERNAL void scm_dynstack_unwind_fluid (scm_t_dynstack *dynstack,
SCM dynamic_state); SCM dynamic_state);
SCM_INTERNAL scm_t_bits* scm_dynstack_find_prompt (scm_t_dynstack *, SCM, SCM_INTERNAL scm_t_bits* scm_dynstack_find_prompt (scm_t_dynstack *, SCM,
scm_t_dynstack_prompt_flags *, scm_t_dynstack_prompt_flags *,

View file

@ -302,52 +302,17 @@ apply_thunk (void *thunk)
return scm_call_0 (SCM_PACK (thunk)); return scm_call_0 (SCM_PACK (thunk));
} }
size_t
scm_prepare_fluids (size_t n, SCM *fluids, SCM *values)
{
size_t j;
/* Ensure that there are no duplicates in the fluids set -- an N^2 operation,
but N will usually be small, so perhaps that's OK. */
for (j = n; j--;)
{
size_t i;
if (SCM_UNLIKELY (!IS_FLUID (fluids[j])))
scm_wrong_type_arg ("with-fluids", 0, fluids[j]);
for (i = j; i--;)
if (scm_is_eq (fluids[i], fluids[j]))
{
values[i] = values[j]; /* later bindings win */
n--;
fluids[j] = fluids[n];
values[j] = values[n];
break;
}
}
return n;
}
void void
scm_swap_fluids (size_t n, SCM *fluids, SCM *values, SCM dynstate) scm_swap_fluid (SCM fluid, SCM value_box, SCM dynstate)
{ {
SCM fluid_vector; SCM fluid_vector, tmp;
size_t i, max = 0; size_t fluid_num;
fluid_num = FLUID_NUM (fluid);
fluid_vector = DYNAMIC_STATE_FLUIDS (dynstate); fluid_vector = DYNAMIC_STATE_FLUIDS (dynstate);
/* We could cache the max in the with-fluids, but that would take more mem, if (SCM_UNLIKELY (fluid_num >= SCM_SIMPLE_VECTOR_LENGTH (fluid_vector)))
and we're touching all the fluids anyway, so this per-swap traversal should
be OK. */
for (i = 0; i < n; i++)
{
size_t num = FLUID_NUM (fluids[i]);
max = (max > num) ? max : num;
}
if (SCM_UNLIKELY (max >= SCM_SIMPLE_VECTOR_LENGTH (fluid_vector)))
{ {
/* Lazily grow the current thread's dynamic state. */ /* Lazily grow the current thread's dynamic state. */
grow_dynamic_state (dynstate); grow_dynamic_state (dynstate);
@ -355,17 +320,9 @@ scm_swap_fluids (size_t n, SCM *fluids, SCM *values, SCM dynstate)
fluid_vector = DYNAMIC_STATE_FLUIDS (dynstate); fluid_vector = DYNAMIC_STATE_FLUIDS (dynstate);
} }
/* Bind the fluids. Order doesn't matter, as all fluids are distinct. */ tmp = SCM_SIMPLE_VECTOR_REF (fluid_vector, fluid_num);
for (i = 0; i < n; i++) SCM_SIMPLE_VECTOR_SET (fluid_vector, fluid_num, SCM_VARIABLE_REF (value_box));
{ SCM_VARIABLE_SET (value_box, tmp);
size_t fluid_num;
SCM x;
fluid_num = FLUID_NUM (fluids[i]);
x = SCM_SIMPLE_VECTOR_REF (fluid_vector, fluid_num);
SCM_SIMPLE_VECTOR_SET (fluid_vector, fluid_num, values[i]);
values[i] = x;
}
} }
SCM_DEFINE (scm_with_fluids, "with-fluids*", 3, 0, 0, SCM_DEFINE (scm_with_fluids, "with-fluids*", 3, 0, 0,
@ -387,7 +344,6 @@ scm_c_with_fluids (SCM fluids, SCM values, SCM (*cproc) (), void *cdata)
{ {
SCM ans; SCM ans;
long flen, vlen, i; long flen, vlen, i;
SCM *fluidsv, *valuesv;
scm_i_thread *thread = SCM_I_CURRENT_THREAD; scm_i_thread *thread = SCM_I_CURRENT_THREAD;
SCM_VALIDATE_LIST_COPYLEN (1, fluids, flen); SCM_VALIDATE_LIST_COPYLEN (1, fluids, flen);
@ -395,24 +351,19 @@ scm_c_with_fluids (SCM fluids, SCM values, SCM (*cproc) (), void *cdata)
if (flen != vlen) if (flen != vlen)
scm_out_of_range (s_scm_with_fluids, values); scm_out_of_range (s_scm_with_fluids, values);
if (SCM_UNLIKELY (flen == 0))
return cproc (cdata);
fluidsv = alloca (sizeof(SCM)*flen);
valuesv = alloca (sizeof(SCM)*flen);
for (i = 0; i < flen; i++) for (i = 0; i < flen; i++)
{ {
fluidsv[i] = SCM_CAR (fluids); scm_dynstack_push_fluid (&thread->dynstack,
SCM_CAR (fluids), SCM_CAR (values),
thread->dynamic_state);
fluids = SCM_CDR (fluids); fluids = SCM_CDR (fluids);
valuesv[i] = SCM_CAR (values);
values = SCM_CDR (values); values = SCM_CDR (values);
} }
scm_dynstack_push_fluids (&thread->dynstack, flen, fluidsv, valuesv,
thread->dynamic_state);
ans = cproc (cdata); ans = cproc (cdata);
scm_dynstack_unwind_fluids (&thread->dynstack, thread->dynamic_state);
for (i = 0; i < flen; i++)
scm_dynstack_unwind_fluid (&thread->dynstack, thread->dynamic_state);
return ans; return ans;
} }
@ -432,10 +383,10 @@ scm_c_with_fluid (SCM fluid, SCM value, SCM (*cproc) (), void *cdata)
SCM ans; SCM ans;
scm_i_thread *thread = SCM_I_CURRENT_THREAD; scm_i_thread *thread = SCM_I_CURRENT_THREAD;
scm_dynstack_push_fluids (&thread->dynstack, 1, &fluid, &value, scm_dynstack_push_fluid (&thread->dynstack, fluid, value,
thread->dynamic_state); thread->dynamic_state);
ans = cproc (cdata); ans = cproc (cdata);
scm_dynstack_unwind_fluids (&thread->dynstack, thread->dynamic_state); scm_dynstack_unwind_fluid (&thread->dynstack, thread->dynamic_state);
return ans; return ans;
} }

View file

@ -3,7 +3,7 @@
#ifndef SCM_FLUIDS_H #ifndef SCM_FLUIDS_H
#define SCM_FLUIDS_H #define SCM_FLUIDS_H
/* Copyright (C) 1996,2000,2001, 2006, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. /* Copyright (C) 1996,2000,2001, 2006, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License * modify it under the terms of the GNU Lesser General Public License
@ -59,9 +59,7 @@ SCM_API SCM scm_fluid_set_x (SCM fluid, SCM value);
SCM_API SCM scm_fluid_unset_x (SCM fluid); SCM_API SCM scm_fluid_unset_x (SCM fluid);
SCM_API SCM scm_fluid_bound_p (SCM fluid); SCM_API SCM scm_fluid_bound_p (SCM fluid);
SCM_INTERNAL size_t scm_prepare_fluids (size_t n, SCM *fluids, SCM *vals); SCM_INTERNAL void scm_swap_fluid (SCM fluid, SCM value_box, SCM dynamic_state);
SCM_INTERNAL void scm_swap_fluids (size_t n, SCM *fluids, SCM *vals,
SCM dynamic_state);
SCM_API SCM scm_c_with_fluids (SCM fluids, SCM vals, SCM_API SCM scm_c_with_fluids (SCM fluids, SCM vals,
SCM (*cproc)(void *), void *cdata); SCM (*cproc)(void *), void *cdata);

View file

@ -84,8 +84,8 @@ static SCM
do_push_fluid (SCM fluid, SCM val) do_push_fluid (SCM fluid, SCM val)
{ {
scm_i_thread *thread = SCM_I_CURRENT_THREAD; scm_i_thread *thread = SCM_I_CURRENT_THREAD;
scm_dynstack_push_fluids (&thread->dynstack, 1, &fluid, &val, scm_dynstack_push_fluid (&thread->dynstack, fluid, val,
thread->dynamic_state); thread->dynamic_state);
return SCM_UNSPECIFIED; return SCM_UNSPECIFIED;
} }
@ -93,7 +93,7 @@ static SCM
do_pop_fluid (void) do_pop_fluid (void)
{ {
scm_i_thread *thread = SCM_I_CURRENT_THREAD; scm_i_thread *thread = SCM_I_CURRENT_THREAD;
scm_dynstack_unwind_fluids (&thread->dynstack, thread->dynamic_state); scm_dynstack_unwind_fluid (&thread->dynstack, thread->dynamic_state);
return SCM_UNSPECIFIED; return SCM_UNSPECIFIED;
} }

View file

@ -2519,39 +2519,34 @@ RTL_VM_NAME (SCM vm, SCM program, SCM *argv, size_t nargs_)
NEXT (1); NEXT (1);
} }
/* wind-fluids fluid-base:24 _:8 n:24 value0:24 0:8 ... /* push-fluid fluid:12 value:12
* *
* Dynamically bind N fluids to values. The fluids are expected to be * Dynamically bind N fluids to values. The fluids are expected to be
* allocated in a continguous range on the stack, starting from * allocated in a continguous range on the stack, starting from
* FLUID-BASE. The values do not have this restriction. * FLUID-BASE. The values do not have this restriction.
*/ */
VM_DEFINE_OP (69, wind_fluids, "wind-fluids", OP2 (U8_U24, X8_R24)) VM_DEFINE_OP (69, push_fluid, "push-fluid", OP1 (U8_U12_U12))
#if 0
{ {
scm_t_uint32 fluid_base, n; scm_t_uint32 fluid, value;
SCM_UNPACK_RTL_24 (op, fluid_base); SCM_UNPACK_RTL_12_12 (op, fluid, value);
SCM_UNPACK_RTL_24 (ip[1], n);
scm_dynstack_push_fluids_shuffled (&current_thread->dynstack, n, scm_dynstack_push_fluid (&current_thread->dynstack,
&fp[fluid_base], fp, &ip[2], fp[fluid], fp[value],
current_thread->dynamic_state); current_thread->dynamic_state);
NEXT (n + 2); NEXT (1);
} }
#else
abort();
#endif
/* unwind-fluids _:24 /* pop-fluid _:24
* *
* Leave the dynamic extent of a with-fluids expression, restoring the * Leave the dynamic extent of a with-fluids expression, restoring the
* fluids to their previous values. * fluids to their previous values.
*/ */
VM_DEFINE_OP (70, unwind_fluids, "unwind-fluids", OP1 (U8_X24)) VM_DEFINE_OP (70, pop_fluid, "pop-fluid", OP1 (U8_X24))
{ {
/* This function must not allocate. */ /* This function must not allocate. */
scm_dynstack_unwind_fluids (&current_thread->dynstack, scm_dynstack_unwind_fluid (&current_thread->dynstack,
current_thread->dynamic_state); current_thread->dynamic_state);
NEXT (1); NEXT (1);
} }

View file

@ -1495,16 +1495,16 @@ VM_DEFINE_INSTRUCTION (91, push_fluid, "push-fluid", 0, 2, 0)
SCM fluid, val; SCM fluid, val;
POP2 (val, fluid); POP2 (val, fluid);
SYNC_REGISTER (); SYNC_REGISTER ();
scm_dynstack_push_fluids (&current_thread->dynstack, 1, &fluid, &val, scm_dynstack_push_fluid (&current_thread->dynstack, fluid, val,
current_thread->dynamic_state); current_thread->dynamic_state);
NEXT; NEXT;
} }
VM_DEFINE_INSTRUCTION (92, pop_fluid, "pop-fluid", 0, 0, 0) VM_DEFINE_INSTRUCTION (92, pop_fluid, "pop-fluid", 0, 0, 0)
{ {
/* This function must not allocate. */ /* This function must not allocate. */
scm_dynstack_unwind_fluids (&current_thread->dynstack, scm_dynstack_unwind_fluid (&current_thread->dynstack,
current_thread->dynamic_state); current_thread->dynamic_state);
NEXT; NEXT;
} }