mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-02 22:46:30 +02:00
gpgscm: Keep a history of calls for error messages.
* tests/gpgscm/init.scm (vm-history-print): New function. * tests/gpgscm/opdefines.h: New opcodes 'CALLSTACK_POP', 'APPLY_CODE', and 'VM_HISTORY'. * tests/gpgscm/scheme-private.h (struct history): New definition. (struct scheme): New field 'history'. * tests/gpgscm/scheme.c (gc): Mark objects in the history. (history_free): New function. (history_init): Likewise. (history_mark): Likewise. (add_mod): New macro. (sub_mod): Likewise. (tailstack_clear): New function. (callstack_pop): Likewise. (callstack_push): Likewise. (tailstack_push): Likewise. (tailstack_flatten): Likewise. (callstack_flatten): Likewise. (history_flatten): Likewise. (opexe_0): New variable 'callsite', keep track of the expression if it is a call, implement the new opcodes, record function applications in the history. (opexe_6): Implement new opcode. (scheme_init_custom_alloc): Initialize history. (scheme_deinit): Free history. * tests/gpgscm/scheme.h (USE_HISTORY): New macro. -- This patch makes TinySCHEME keep a history of function calls. This history can be used to produce helpful error messages. The history data structure is inspired by MIT/GNU Scheme. Signed-off-by: Justus Winter <justus@g10code.com> fu history
This commit is contained in:
parent
01256694f0
commit
404e8a4136
5 changed files with 339 additions and 4 deletions
|
@ -62,6 +62,34 @@ struct cell {
|
|||
} _object;
|
||||
};
|
||||
|
||||
#if USE_HISTORY
|
||||
/* The history is a two-dimensional ring buffer. A donut-shaped data
|
||||
* structure. This data structure is inspired by MIT/GNU Scheme. */
|
||||
struct history {
|
||||
/* Number of calls to store. Must be a power of two. */
|
||||
size_t N;
|
||||
|
||||
/* Number of tail-calls to store in each call frame. Must be a
|
||||
* power of two. */
|
||||
size_t M;
|
||||
|
||||
/* Masks for fast index calculations. */
|
||||
size_t mask_N;
|
||||
size_t mask_M;
|
||||
|
||||
/* A vector of size N containing calls. */
|
||||
pointer callstack;
|
||||
|
||||
/* A vector of size N containing vectors of size M containing tail
|
||||
* calls. */
|
||||
pointer tailstacks;
|
||||
|
||||
/* Our current position. */
|
||||
size_t n;
|
||||
size_t *m;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct scheme {
|
||||
/* arrays for segments */
|
||||
func_alloc malloc;
|
||||
|
@ -88,6 +116,11 @@ pointer envir; /* stack register for current environment */
|
|||
pointer code; /* register for current code */
|
||||
pointer dump; /* stack register for next evaluation */
|
||||
|
||||
#if USE_HISTORY
|
||||
struct history history; /* we keep track of the call history for
|
||||
* error messages */
|
||||
#endif
|
||||
|
||||
int interactive_repl; /* are we in an interactive REPL? */
|
||||
|
||||
struct cell _sink;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue