1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-16 16:50:21 +02:00

* backtrace.c (display_expression, display_frame): Call

scm_i_unmemoize_expr for unmemoizing a memoized object holding a
	single memoized expression.

	* debug.c (memoized_print): Don't try to unmemoize the memoized
	object, since we can't know whether it holds a single expression
	or a body.

	(scm_mem_to_proc): Removed check for lambda expression, since it
	was moot anyway.  Whoever uses these functions for debugging
	purposes should know what they do: Creating invalid memoized code
	will cause crashes, independent of whether this check is present
	or not.

	(scm_proc_to_mem): Take the closure's code as it is and don't
	append a SCM_IM_LAMBDA isym.  To allow easier debugging, the
	memoized code should not be modified.

	* debug.[ch] (scm_unmemoize, scm_i_unmemoize_expr): Removed
	scm_unmemoize from public use, but made scm_i_unmemoize_expr
	available as a guile internal function instead.  However,
	scm_i_unmemoize_expr will only work on memoized objects that hold
	a single memoized expression.  It won't work with bodies.

	* debug.c (scm_procedure_source), macros.c (macro_print), print.c
	(scm_iprin1): Call scm_i_unmemocopy_body for unmemoizing a body,
	i. e. a list of expressions.

	* eval.c (unmemoize_exprs): Drop internal body markers from the
	output during unmemoization.

	* eval.[ch] (scm_unmemocopy, scm_i_unmemocopy_expr,
	scm_i_unmemocopy_body): Removed scm_unmemocopy from public use,
	but made scm_i_unmemocopy_expr and scm_i_unmemocopy_body available
	as guile internal functions instead.  scm_i_unmemoize_expr will
	only work on a single memoized expression, while
	scm_i_unmemocopy_body will only work on bodies.
This commit is contained in:
Dirk Herrmann 2004-06-27 12:34:54 +00:00
parent 90df793f67
commit 9fcf3cbb81
9 changed files with 98 additions and 36 deletions

21
NEWS
View file

@ -670,6 +670,20 @@ On platforms that have them, these types are identical to intmax_t and
uintmax_t, respectively. On other platforms, they are identical to uintmax_t, respectively. On other platforms, they are identical to
the largest integer types that Guile knows about. the largest integer types that Guile knows about.
** scm_unmemocopy and scm_unmemoize have been removed from public use.
For guile internal use, the functions scm_i_unmemocopy_expr,
scm_i_unmemocopy_body and scm_i_unmemoize_expr are provided to replace
scm_unmemocopy and scm_unmemoize. User code should not have used
scm_unmemocopy and scm_unmemoize and thus should not use the replacement
functions also.
Background: Formerly, scm_unmemocopy and scm_unmemoize would have allowed to
unmemoize a single expression as well as a sequence of body forms. This would
have lead to problems when unmemoizing code of the new memoizer. Now the two
cases have to be distinguished.
** Many public #defines with generic names have been made private. ** Many public #defines with generic names have been made private.
#defines with generic names like HAVE_FOO or SIZEOF_FOO have been made #defines with generic names like HAVE_FOO or SIZEOF_FOO have been made
@ -813,13 +827,6 @@ Guile always defines
scm_t_timespec scm_t_timespec
** The function scm_unmemocopy now expects a sequence of body forms
Formerly, scm_unmemocopy would have accepted both, a single expression and a
sequence of body forms for unmemoization. Now, it only accepts only a
sequence of body forms, which was the normal way of using it. Passing it a
single expression won't work any more.
** The macro SCM_IFLAGP now only returns true for flags ** The macro SCM_IFLAGP now only returns true for flags
User code should never have used this macro anyway. And, you should not use User code should never have used this macro anyway. And, you should not use

View file

@ -1,3 +1,43 @@
2004-06-27 Dirk Herrmann <dirk@dirk-herrmanns-seiten.de>
* backtrace.c (display_expression, display_frame): Call
scm_i_unmemoize_expr for unmemoizing a memoized object holding a
single memoized expression.
* debug.c (memoized_print): Don't try to unmemoize the memoized
object, since we can't know whether it holds a single expression
or a body.
(scm_mem_to_proc): Removed check for lambda expression, since it
was moot anyway. Whoever uses these functions for debugging
purposes should know what they do: Creating invalid memoized code
will cause crashes, independent of whether this check is present
or not.
(scm_proc_to_mem): Take the closure's code as it is and don't
append a SCM_IM_LAMBDA isym. To allow easier debugging, the
memoized code should not be modified.
* debug.[ch] (scm_unmemoize, scm_i_unmemoize_expr): Removed
scm_unmemoize from public use, but made scm_i_unmemoize_expr
available as a guile internal function instead. However,
scm_i_unmemoize_expr will only work on memoized objects that hold
a single memoized expression. It won't work with bodies.
* debug.c (scm_procedure_source), macros.c (macro_print), print.c
(scm_iprin1): Call scm_i_unmemocopy_body for unmemoizing a body,
i. e. a list of expressions.
* eval.c (unmemoize_exprs): Drop internal body markers from the
output during unmemoization.
* eval.[ch] (scm_unmemocopy, scm_i_unmemocopy_expr,
scm_i_unmemocopy_body): Removed scm_unmemocopy from public use,
but made scm_i_unmemocopy_expr and scm_i_unmemocopy_body available
as guile internal functions instead. scm_i_unmemoize_expr will
only work on a single memoized expression, while
scm_i_unmemocopy_body will only work on bodies.
2004-06-21 Dirk Herrmann <dirk@dirk-herrmanns-seiten.de> 2004-06-21 Dirk Herrmann <dirk@dirk-herrmanns-seiten.de>
* eval.c (unmemoize_exprs): Handle semi-memoized code. * eval.c (unmemoize_exprs): Handle semi-memoized code.

View file

@ -188,14 +188,14 @@ display_expression (SCM frame, SCM pname, SCM source, SCM port)
{ {
scm_puts (" in expression ", port); scm_puts (" in expression ", port);
pstate->writingp = 1; pstate->writingp = 1;
scm_iprin1 (scm_unmemoize (source), port, pstate); scm_iprin1 (scm_i_unmemoize_expr (source), port, pstate);
} }
} }
else if (SCM_MEMOIZEDP (source)) else if (SCM_MEMOIZEDP (source))
{ {
scm_puts ("In expression ", port); scm_puts ("In expression ", port);
pstate->writingp = 1; pstate->writingp = 1;
scm_iprin1 (scm_unmemoize (source), port, pstate); scm_iprin1 (scm_i_unmemoize_expr (source), port, pstate);
} }
scm_puts (":\n", port); scm_puts (":\n", port);
scm_free_print_state (print_state); scm_free_print_state (print_state);
@ -602,7 +602,7 @@ display_frame (SCM frame, int nfield, int indentation, SCM sport, SCM port, scm_
? scm_source_property (source, scm_sym_copy) ? scm_source_property (source, scm_sym_copy)
: SCM_BOOL_F); : SCM_BOOL_F);
SCM umcopy = (SCM_MEMOIZEDP (source) SCM umcopy = (SCM_MEMOIZEDP (source)
? scm_unmemoize (source) ? scm_i_unmemoize_expr (source)
: SCM_BOOL_F); : SCM_BOOL_F);
display_frame_expr ("(", display_frame_expr ("(",
SCM_CONSP (copy) ? copy : umcopy, SCM_CONSP (copy) ? copy : umcopy,

View file

@ -123,11 +123,7 @@ memoized_print (SCM obj, SCM port, scm_print_state *pstate)
int writingp = SCM_WRITINGP (pstate); int writingp = SCM_WRITINGP (pstate);
scm_puts ("#<memoized ", port); scm_puts ("#<memoized ", port);
SCM_SET_WRITINGP (pstate, 1); SCM_SET_WRITINGP (pstate, 1);
#ifdef GUILE_DEBUG
scm_iprin1 (SCM_MEMOIZED_EXP (obj), port, pstate); scm_iprin1 (SCM_MEMOIZED_EXP (obj), port, pstate);
#else
scm_iprin1 (scm_unmemoize (obj), port, pstate);
#endif
SCM_SET_WRITINGP (pstate, writingp); SCM_SET_WRITINGP (pstate, writingp);
scm_putc ('>', port); scm_putc ('>', port);
return 1; return 1;
@ -246,7 +242,7 @@ SCM_DEFINE (scm_memcons, "memcons", 2, 1, 0,
SCM_DEFINE (scm_mem_to_proc, "mem->proc", 1, 0, 0, SCM_DEFINE (scm_mem_to_proc, "mem->proc", 1, 0, 0,
(SCM obj), (SCM obj),
"Convert a memoized object (which must be a lambda expression)\n" "Convert a memoized object (which must represent a body)\n"
"to a procedure.") "to a procedure.")
#define FUNC_NAME s_scm_mem_to_proc #define FUNC_NAME s_scm_mem_to_proc
{ {
@ -254,9 +250,7 @@ SCM_DEFINE (scm_mem_to_proc, "mem->proc", 1, 0, 0,
SCM_VALIDATE_MEMOIZED (1, obj); SCM_VALIDATE_MEMOIZED (1, obj);
env = SCM_MEMOIZED_ENV (obj); env = SCM_MEMOIZED_ENV (obj);
obj = SCM_MEMOIZED_EXP (obj); obj = SCM_MEMOIZED_EXP (obj);
if (!SCM_CONSP (obj) || !SCM_EQ_P (SCM_CAR (obj), SCM_IM_LAMBDA)) return scm_closure (obj, env);
SCM_MISC_ERROR ("expected lambda expression", scm_list_1 (obj));
return scm_closure (SCM_CDR (obj), env);
} }
#undef FUNC_NAME #undef FUNC_NAME
@ -266,20 +260,19 @@ SCM_DEFINE (scm_proc_to_mem, "proc->mem", 1, 0, 0,
#define FUNC_NAME s_scm_proc_to_mem #define FUNC_NAME s_scm_proc_to_mem
{ {
SCM_VALIDATE_CLOSURE (1, obj); SCM_VALIDATE_CLOSURE (1, obj);
return scm_make_memoized (scm_cons (SCM_IM_LAMBDA, SCM_CODE (obj)), return scm_make_memoized (SCM_CODE (obj), SCM_ENV (obj));
SCM_ENV (obj));
} }
#undef FUNC_NAME #undef FUNC_NAME
#endif /* GUILE_DEBUG */ #endif /* GUILE_DEBUG */
SCM_DEFINE (scm_unmemoize, "unmemoize", 1, 0, 0, SCM_DEFINE (scm_i_unmemoize_expr, "unmemoize-expr", 1, 0, 0,
(SCM m), (SCM m),
"Unmemoize the memoized expression @var{m},") "Unmemoize the memoized expression @var{m},")
#define FUNC_NAME s_scm_unmemoize #define FUNC_NAME s_scm_i_unmemoize_expr
{ {
SCM_VALIDATE_MEMOIZED (1, m); SCM_VALIDATE_MEMOIZED (1, m);
return scm_unmemocopy (SCM_MEMOIZED_EXP (m), SCM_MEMOIZED_ENV (m)); return scm_i_unmemocopy_expr (SCM_MEMOIZED_EXP (m), SCM_MEMOIZED_ENV (m));
} }
#undef FUNC_NAME #undef FUNC_NAME
@ -342,7 +335,7 @@ SCM_DEFINE (scm_procedure_source, "procedure-source", 1, 0, 0,
const SCM env = SCM_EXTEND_ENV (formals, SCM_EOL, SCM_ENV (proc)); const SCM env = SCM_EXTEND_ENV (formals, SCM_EOL, SCM_ENV (proc));
return scm_cons2 (scm_sym_lambda, return scm_cons2 (scm_sym_lambda,
scm_i_finite_list_copy (formals), scm_i_finite_list_copy (formals),
scm_unmemocopy (body, env)); scm_i_unmemocopy_body (body, env));
} }
} }
case scm_tcs_struct: case scm_tcs_struct:

View file

@ -161,8 +161,9 @@ SCM_API SCM scm_memoized_p (SCM obj);
SCM_API SCM scm_with_traps (SCM thunk); SCM_API SCM scm_with_traps (SCM thunk);
SCM_API SCM scm_evaluator_traps (SCM setting); SCM_API SCM scm_evaluator_traps (SCM setting);
SCM_API SCM scm_debug_options (SCM setting); SCM_API SCM scm_debug_options (SCM setting);
SCM_API SCM scm_unmemoize (SCM memoized);
SCM_API SCM scm_make_debugobj (scm_t_debug_frame *debug); SCM_API SCM scm_make_debugobj (scm_t_debug_frame *debug);
SCM_API SCM scm_i_unmemoize_expr (SCM memoized);
SCM_API void scm_init_debug (void); SCM_API void scm_init_debug (void);
#ifdef GUILE_DEBUG #ifdef GUILE_DEBUG

View file

@ -580,18 +580,25 @@ static SCM
unmemoize_exprs (const SCM exprs, const SCM env) unmemoize_exprs (const SCM exprs, const SCM env)
{ {
SCM r_result = SCM_EOL; SCM r_result = SCM_EOL;
SCM expr_idx; SCM expr_idx = exprs;
SCM um_expr; SCM um_expr;
/* Note that due to the current lazy memoizer we may find partially memoized /* Note that due to the current lazy memoizer we may find partially memoized
* code during execution. In such code we have to expect improper lists of * code during execution. In such code, lists of expressions that stem from
* a body form may start with an ISYM if the body itself has not yet been
* memoized. This isym is just an internal marker to indicate that the body
* still needs to be memoized. It is dropped during unmemoization. */
if (SCM_CONSP (expr_idx) && SCM_ISYMP (SCM_CAR (expr_idx)))
expr_idx = SCM_CDR (expr_idx);
/* Moreover, in partially memoized code we have to expect improper lists of
* expressions: On the one hand, for such code syntax checks have not yet * expressions: On the one hand, for such code syntax checks have not yet
* fully been performed, on the other hand, there may be even legal code * fully been performed, on the other hand, there may be even legal code
* like '(a . b) appear as an improper list of expressions as long as the * like '(a . b) appear as an improper list of expressions as long as the
* quote expression is still in its unmemoized form. For this reason, the * quote expression is still in its unmemoized form. For this reason, the
* following code handles improper lists of expressions until memoization * following code handles improper lists of expressions until memoization
* and execution have been completely separated. */ * and execution have been completely separated. */
for (expr_idx = exprs; SCM_CONSP (expr_idx); expr_idx = SCM_CDR (expr_idx)) for (; SCM_CONSP (expr_idx); expr_idx = SCM_CDR (expr_idx))
{ {
const SCM expr = SCM_CAR (expr_idx); const SCM expr = SCM_CAR (expr_idx);
um_expr = unmemoize_expression (expr, env); um_expr = unmemoize_expression (expr, env);
@ -2383,10 +2390,11 @@ unmemoize_builtin_macro (const SCM expr, const SCM env)
} }
/* scm_unmemocopy takes a memoized body together with its environment and /* scm_i_unmemocopy_expr and scm_i_unmemocopy_body take a memoized expression
* rewrites it to its original form. Thus, it is the inversion of the rewrite * respectively a memoized body together with its environment and rewrite it
* rules above. The procedure is not optimized for speed. It's used in * to its original form. Thus, these functions are the inversion of the
* scm_unmemoize, scm_procedure_source, macro_print and scm_iprin1. * rewrite rules above. The procedure is not optimized for speed. It's used
* in scm_i_unmemoize_expr, scm_procedure_source, macro_print and scm_iprin1.
* *
* Unmemoizing is not a reliable process. You cannot in general expect to get * Unmemoizing is not a reliable process. You cannot in general expect to get
* the original source back. * the original source back.
@ -2395,7 +2403,19 @@ unmemoize_builtin_macro (const SCM expr, const SCM env)
* to change. */ * to change. */
SCM SCM
scm_unmemocopy (SCM forms, SCM env) scm_i_unmemocopy_expr (SCM expr, SCM env)
{
const SCM source_properties = scm_whash_lookup (scm_source_whash, expr);
const SCM um_expr = unmemoize_expression (expr, env);
if (!SCM_FALSEP (source_properties))
scm_whash_insert (scm_source_whash, um_expr, source_properties);
return um_expr;
}
SCM
scm_i_unmemocopy_body (SCM forms, SCM env)
{ {
const SCM source_properties = scm_whash_lookup (scm_source_whash, forms); const SCM source_properties = scm_whash_lookup (scm_source_whash, forms);
const SCM um_forms = unmemoize_exprs (forms, env); const SCM um_forms = unmemoize_exprs (forms, env);

View file

@ -128,7 +128,6 @@ SCM_API SCM scm_sym_args;
SCM_API SCM * scm_ilookup (SCM iloc, SCM env); SCM_API SCM * scm_ilookup (SCM iloc, SCM env);
SCM_API SCM * scm_lookupcar (SCM vloc, SCM genv, int check); SCM_API SCM * scm_lookupcar (SCM vloc, SCM genv, int check);
SCM_API SCM scm_unmemocopy (SCM form, SCM env);
SCM_API SCM scm_eval_car (SCM pair, SCM env); SCM_API SCM scm_eval_car (SCM pair, SCM env);
SCM_API SCM scm_eval_body (SCM code, SCM env); SCM_API SCM scm_eval_body (SCM code, SCM env);
SCM_API SCM scm_eval_args (SCM i, SCM env, SCM proc); SCM_API SCM scm_eval_args (SCM i, SCM env, SCM proc);
@ -197,6 +196,8 @@ SCM_API SCM scm_eval_x (SCM exp, SCM module);
SCM_API void scm_i_print_iloc (SCM /*iloc*/, SCM /*port*/); SCM_API void scm_i_print_iloc (SCM /*iloc*/, SCM /*port*/);
SCM_API void scm_i_print_isym (SCM /*isym*/, SCM /*port*/); SCM_API void scm_i_print_isym (SCM /*isym*/, SCM /*port*/);
SCM_API SCM scm_i_unmemocopy_expr (SCM expr, SCM env);
SCM_API SCM scm_i_unmemocopy_body (SCM forms, SCM env);
SCM_API void scm_init_eval (void); SCM_API void scm_init_eval (void);

View file

@ -66,7 +66,7 @@ macro_print (SCM macro, SCM port, scm_print_state *pstate)
SCM formals = SCM_CLOSURE_FORMALS (code); SCM formals = SCM_CLOSURE_FORMALS (code);
SCM env = SCM_ENV (code); SCM env = SCM_ENV (code);
SCM xenv = SCM_EXTEND_ENV (formals, SCM_EOL, env); SCM xenv = SCM_EXTEND_ENV (formals, SCM_EOL, env);
SCM src = scm_unmemocopy (SCM_CODE (code), xenv); SCM src = scm_i_unmemocopy_body (SCM_CODE (code), xenv);
scm_putc (' ', port); scm_putc (' ', port);
scm_iprin1 (src, port, pstate); scm_iprin1 (src, port, pstate);
} }

View file

@ -455,7 +455,7 @@ scm_iprin1 (SCM exp, SCM port, scm_print_state *pstate)
{ {
SCM env = SCM_ENV (exp); SCM env = SCM_ENV (exp);
SCM xenv = SCM_EXTEND_ENV (formals, SCM_EOL, env); SCM xenv = SCM_EXTEND_ENV (formals, SCM_EOL, env);
SCM src = scm_unmemocopy (SCM_CODE (exp), xenv); SCM src = scm_i_unmemocopy_body (SCM_CODE (exp), xenv);
ENTER_NESTED_DATA (pstate, exp, circref); ENTER_NESTED_DATA (pstate, exp, circref);
scm_iprin1 (src, port, pstate); scm_iprin1 (src, port, pstate);
EXIT_NESTED_DATA (pstate); EXIT_NESTED_DATA (pstate);