diff --git a/libguile/ChangeLog b/libguile/ChangeLog index f6b6c99ed..60f3bcd58 100644 --- a/libguile/ChangeLog +++ b/libguile/ChangeLog @@ -1,3 +1,39 @@ +2003-09-16 Dirk Herrmann + + This set of patches eliminates the dependency between the + implementation of evaluator specific memoization codes and special + constants like #f, '() etc. ('flags'), which are not evaluator + specific. The goal is to remove definitions of evaluator + memoization codes completely from the public interface. This will + make it possible to experiment more freely with optimizations of + guile's internal representation of memoized code. + + * objects.c (scm_class_of): Eliminate dependency on SCM_ISYMNUM. + + * print.c (iflagnames): New array, holding the printed names of + guile's special constants ('flags'). + + (scm_isymnames): Now holds only the printed names of the + memoization codes. + + (scm_iprin1): Separate the handling of memoization codes and + guile's special constants. + + * tags.h (scm_tc9_flag, SCM_ITAG9, SCM_MAKE_ITAG9, SCM_ITAG9_DATA, + SCM_IFLAGNUM): new + + (scm_tc8_char, scm_tc8_iloc, SCM_BOOL_F, SCM_BOOL_T, + SCM_UNDEFINED, SCM_EOF_VAL, SCM_EOL, SCM_UNSPECIFIED, SCM_UNBOUND, + SCM_ELISP_NIL, SCM_IM_DISPATCH, SCM_IM_SLOT_REF, + SCM_IM_SLOT_SET_X, SCM_IM_DELAY, SCM_IM_FUTURE, + SCM_IM_CALL_WITH_VALUES, SCM_IM_NIL_COND, SCM_IM_BIND): Changed + values. + + (SCM_IFLAGP): SCM_IFLAGP now only tests for flags. + + (SCM_IFLAGP, SCM_MAKIFLAG, SCM_IFLAGNUM): Generalized to use the + tc9 macros and scm_tc9_flag. + 2003-09-15 Marius Vollmer * posix.c (scm_setgroups): Check that the gid list is not too diff --git a/libguile/objects.c b/libguile/objects.c index 0f4443cd8..be9481c9a 100644 --- a/libguile/objects.c +++ b/libguile/objects.c @@ -71,19 +71,12 @@ SCM_DEFINE (scm_class_of, "class-of", 1, 0, 0, case scm_tc3_imm24: if (SCM_CHARP (x)) return scm_class_char; + else if (SCM_BOOLP (x)) + return scm_class_boolean; + else if (SCM_NULLP (x)) + return scm_class_null; else - { - switch (SCM_ISYMNUM (x)) - { - case SCM_ISYMNUM (SCM_BOOL_F): - case SCM_ISYMNUM (SCM_BOOL_T): - return scm_class_boolean; - case SCM_ISYMNUM (SCM_EOL): - return scm_class_null; - default: - return scm_class_unknown; - } - } + return scm_class_unknown; case scm_tc3_cons: switch (SCM_TYP7 (x)) diff --git a/libguile/print.c b/libguile/print.c index af297941d..8b9c506be 100644 --- a/libguile/print.c +++ b/libguile/print.c @@ -49,9 +49,29 @@ * This table must agree with the declarations in scm.h: {Immediate Symbols}. */ +/* This table must agree with the list of flags in tags.h. */ +static const char *iflagnames[] = +{ + "#f", + "#t", + "#", + "#", + "()", + "#", + + /* Unbound slot marker for GOOPS. For internal use in GOOPS only. */ + "#", + + /* Elisp nil value. This is its Scheme name; whenever it's printed in + * Elisp, it should appear as the symbol `nil'. */ + "#nil" +}; + +/* This table must agree with the list of SCM_IM_ constants in tags.h */ char *scm_isymnames[] = { - /* This table must agree with the list of SCM_IM_ constants in tags.h */ + /* Short instructions */ + "#@and", "#@begin", "#@case", @@ -65,39 +85,23 @@ char *scm_isymnames[] = "#@or", "#@quote", "#@set!", + + + /* Long instructions */ + "#@define", "#@apply", "#@call-with-current-continuation", - - /* user visible ISYMS */ - /* other keywords */ - /* Flags */ - - "#f", - "#t", - "#", - "#", - "()", - "#", "#@dispatch", "#@slot-ref", "#@slot-set!", - - /* Multi-language support */ - - "#@nil-cond", - "#@bind", - "#@delay", "#@future", "#@call-with-values", - "#", - - /* Elisp nil value. This is its Scheme name; whenever it's printed - in Elisp, it should appear as the symbol `nil'. */ - - "#nil" + /* Multi-language support */ + "#@nil-cond", + "#@bind" }; scm_t_option scm_print_opts[] = { @@ -434,8 +438,15 @@ scm_iprin1 (SCM exp, SCM port, scm_print_state *pstate) scm_putc (i, port); } else if (SCM_IFLAGP (exp) + && ((size_t) SCM_IFLAGNUM (exp) < (sizeof iflagnames / sizeof (char *)))) + { + scm_puts (iflagnames [SCM_IFLAGNUM (exp)], port); + } + else if (SCM_ISYMP (exp) && ((size_t) SCM_ISYMNUM (exp) < (sizeof scm_isymnames / sizeof (char *)))) + { scm_puts (SCM_ISYMCHARS (exp), port); + } else if (SCM_ILOCP (exp)) { scm_puts ("#@", port); diff --git a/libguile/tags.h b/libguile/tags.h index 4aa8764e7..bc53ff23d 100644 --- a/libguile/tags.h +++ b/libguile/tags.h @@ -317,9 +317,9 @@ typedef unsigned long scm_t_bits; * first dispatch is based on the tc7-code. The second * dispatch is based on the actual byte code that is extracted * from the upper bits. - * x1-1110-100: characters with x as their least significant bit - * 10-1110-100: various constants ('flags') - * x1-1111-100: evaluator byte codes ('ilocs') + * x1-1110-100: evaluator byte codes ('ilocs') + * x1-1111-100: characters with x as their least significant bit + * 10-1111-100: various constants ('flags') * * * Summary of type codes on the heap @@ -493,44 +493,71 @@ typedef unsigned long scm_t_bits; enum scm_tags { - scm_tc8_char = 0xf4, - scm_tc8_iloc = 0xfc + scm_tc8_iloc = 0xf4, + scm_tc8_char = 0xfc, + scm_tc9_flag = 0x17c }; #define SCM_ITAG8(X) (SCM_UNPACK (X) & 0xff) #define SCM_MAKE_ITAG8(X, TAG) SCM_PACK (((X) << 8) + TAG) #define SCM_ITAG8_DATA(X) (SCM_UNPACK (X) >> 8) +#define SCM_ITAG9(X) (SCM_UNPACK (X) & 0x1ff) +#define SCM_MAKE_ITAG9(X, TAG) SCM_PACK (((X) << 9) + TAG) +#define SCM_ITAG9_DATA(X) (SCM_UNPACK (X) >> 9) + -/* Immediate Symbols, Special Symbols, Flags (various constants). - */ +/* Flags (various constants and special objects). The indices of the flags + * must agree with the declarations in print.c: iflagnames. */ + +#define SCM_IFLAGP(n) (SCM_ITAG9 (n) == scm_tc9_flag) +#define SCM_MAKIFLAG(n) SCM_MAKE_ITAG9 ((n), scm_tc9_flag) +#define SCM_IFLAGNUM(n) (SCM_ITAG9_DATA (n)) + +#define SCM_BOOL_F SCM_MAKIFLAG (0) +#define SCM_BOOL_T SCM_MAKIFLAG (1) +#define SCM_UNDEFINED SCM_MAKIFLAG (2) +#define SCM_EOF_VAL SCM_MAKIFLAG (3) +#define SCM_EOL SCM_MAKIFLAG (4) +#define SCM_UNSPECIFIED SCM_MAKIFLAG (5) + +/* When a variable is unbound this is marked by the SCM_UNDEFINED + * value. The following is an unbound value which can be handled on + * the Scheme level, i.e., it can be stored in and retrieved from a + * Scheme variable. This value is only intended to mark an unbound + * slot in GOOPS. It is needed now, but we should probably rewrite + * the code which handles this value in C so that SCM_UNDEFINED can be + * used instead. It is not ideal to let this kind of unique and + * strange values loose on the Scheme level. */ +#define SCM_UNBOUND SCM_MAKIFLAG (6) + +/* The Elisp nil value. */ +#define SCM_ELISP_NIL SCM_MAKIFLAG (7) + + +#define SCM_UNBNDP(x) (SCM_EQ_P ((x), SCM_UNDEFINED)) + + +/* Short instructions ('special symbols'), long instructions ('immediate + * symbols'). The indices of the SCM_IM_ symbols must agree with the + * declarations in print.c: scm_isymnames. */ + +#define SCM_MAKSPCSYM(n) SCM_PACK (((n) << 9) + ((n) << 3) + 4L) +#define SCM_MAKISYM(n) SCM_PACK (((n) << 9) + 0x6cL) /* SCM_ISYMP tests for ISPCSYM and ISYM */ #define SCM_ISYMP(n) ((0x187 & SCM_UNPACK (n)) == 4) - -/* SCM_IFLAGP tests for ISPCSYM, ISYM and IFLAG */ -#define SCM_IFLAGP(n) ((0x87 & SCM_UNPACK (n)) == 4) #define SCM_ISYMNUM(n) (SCM_UNPACK (n) >> 9) -#define SCM_ISYMCHARS(n) (scm_isymnames[SCM_ISYMNUM (n)]) -#define SCM_MAKSPCSYM(n) SCM_PACK (((n) << 9) + ((n) << 3) + 4L) -#define SCM_MAKISYM(n) SCM_PACK (((n) << 9) + 0x6cL) -#define SCM_MAKIFLAG(n) SCM_PACK (((n) << 9) + 0x174L) - SCM_API char *scm_isymnames[]; /* defined in print.c */ - -/* This table must agree with the declarations - * in print.c: {Names of immediate symbols}. - * - * These are used only in eval but their values - * have to be allocated here. - */ +#define SCM_ISYMCHARS(n) (scm_isymnames[SCM_ISYMNUM (n)]) /* Evaluator bytecodes (short instructions): These are uniquely identified by * their tc7 value. This makes it possible for the evaluator to dispatch on * them in one step. However, the type system allows for at most 13 short * instructions. Consequently, the most frequent instructions are chosen to - * be represented as short instructions. */ + * be represented as short instructions. These constants are used only in + * eval but their values have to be allocated here. */ #define SCM_IM_AND SCM_MAKSPCSYM (0) #define SCM_IM_BEGIN SCM_MAKSPCSYM (1) @@ -546,11 +573,14 @@ SCM_API char *scm_isymnames[]; /* defined in print.c */ #define SCM_IM_QUOTE SCM_MAKSPCSYM (11) #define SCM_IM_SET_X SCM_MAKSPCSYM (12) + /* Evaluator bytecodes (long instructions): All these share a common tc7 - * value. Thus, the evaluator needs to dispatch on them in two steps. */ + * value. Thus, the evaluator needs to dispatch on them in two steps. These + * constants are used only in eval but their values have to be allocated + * here. */ /* Evaluator bytecode for (define ...) statements. We make it a long - * instruction since the executor will see this bytecode only for a very + * instruction since the evaluator will see this bytecode only for a very * limited number of times, namely once for every top-level and internal * definition: Top-level definitions are only executed once and internal * definitions are converted to letrec expressions. */ @@ -558,40 +588,17 @@ SCM_API char *scm_isymnames[]; /* defined in print.c */ #define SCM_IM_APPLY SCM_MAKISYM (14) #define SCM_IM_CONT SCM_MAKISYM (15) -#define SCM_BOOL_F SCM_MAKIFLAG (16) -#define SCM_BOOL_T SCM_MAKIFLAG (17) -#define SCM_UNDEFINED SCM_MAKIFLAG (18) -#define SCM_EOF_VAL SCM_MAKIFLAG (19) -#define SCM_EOL SCM_MAKIFLAG (20) -#define SCM_UNSPECIFIED SCM_MAKIFLAG (21) -#define SCM_IM_DISPATCH SCM_MAKISYM (22) -#define SCM_IM_SLOT_REF SCM_MAKISYM (23) -#define SCM_IM_SLOT_SET_X SCM_MAKISYM (24) +#define SCM_IM_DISPATCH SCM_MAKISYM (16) +#define SCM_IM_SLOT_REF SCM_MAKISYM (17) +#define SCM_IM_SLOT_SET_X SCM_MAKISYM (18) +#define SCM_IM_DELAY SCM_MAKISYM (19) +#define SCM_IM_FUTURE SCM_MAKISYM (20) +#define SCM_IM_CALL_WITH_VALUES SCM_MAKISYM (21) /* Multi-language support */ -#define SCM_IM_NIL_COND SCM_MAKISYM (25) -#define SCM_IM_BIND SCM_MAKISYM (26) - -#define SCM_IM_DELAY SCM_MAKISYM (27) -#define SCM_IM_FUTURE SCM_MAKISYM (28) -#define SCM_IM_CALL_WITH_VALUES SCM_MAKISYM (29) - -/* When a variable is unbound this is marked by the SCM_UNDEFINED - * value. The following is an unbound value which can be handled on - * the Scheme level, i.e., it can be stored in and retrieved from a - * Scheme variable. This value is only intended to mark an unbound - * slot in GOOPS. It is needed now, but we should probably rewrite - * the code which handles this value in C so that SCM_UNDEFINED can be - * used instead. It is not ideal to let this kind of unique and - * strange values loose on the Scheme level. - */ -#define SCM_UNBOUND SCM_MAKIFLAG (30) - -#define SCM_UNBNDP(x) (SCM_EQ_P ((x), SCM_UNDEFINED)) - -/* The Elisp nil value. */ -#define SCM_ELISP_NIL SCM_MAKIFLAG (31) +#define SCM_IM_NIL_COND SCM_MAKISYM (22) +#define SCM_IM_BIND SCM_MAKISYM (23)