Hi all, Mario noticed that quite a few eggs broke after the keyword CR was merged. I had a look and it seems to be that many of them break because of either bind (14 reverse dependencies) or foreigners (11 broken reverse dependencies), and they both do something to load already compiled code at compile time.
It turns out that when this happens, and the compiled code being
executed inside the compiler registers an lf[] which refers to
a keyword, *and* that keyword had been interned already (typically
in the source which causes the compiled code to be loaded *afterwards*),
you'll get a weird error that says:
Error: during expansion of (import ...) - bad argument type - not
a symbol: #:destructor
Or something like it.
The minimal repo case I can come up with is:
$ cat foo-code.scm
(print #:foo)
$ cat test.scm
(begin-for-syntax (load "foo-code.so"))
(print #:foo)
$ csc -s foo-code.scm
$ csc test.scm
The fix is relatively straightforward, see attached patch. It just
changes the check_ call to a predicate check for symbol or keyword.
Cheers,
Peter
From 788c29951582802eb351ae8773d75e0828cabb53 Mon Sep 17 00:00:00 2001 From: Peter Bex <[email protected]> Date: Fri, 24 May 2019 22:23:20 +0200 Subject: [PATCH] Fix obscure bug triggered by marking keywords persistable When a keyword has already been read at runtime, and then compiled code is invoked which calls C_h_intern_kw, the keyword will already exist. This is when it is marked as persistent because there's an lf[] referring to it, so it can't be garbage collected. The C_i_persist_symbol() call would then bail out because the offered object is not a symbol but a keyword (the check was done with C_i_check_symbol). This caused several eggs depending on "foreigners" to break, because it exports a macro in the import library which happens to use a keyword. --- runtime.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/runtime.c b/runtime.c index 8a51fd82..30620a22 100644 --- a/runtime.c +++ b/runtime.c @@ -2442,7 +2442,13 @@ C_regparm C_word C_fcall C_i_persist_symbol(C_word sym) C_word bucket; C_SYMBOL_TABLE *stp; - C_i_check_symbol(sym); + /* Normally, this will get called with a symbol, but in + * C_h_intern_kw we may call it with keywords too. + */ + if(!C_truep(C_i_symbolp(sym)) && !C_truep(C_i_keywordp(sym))) { + error_location = C_SCHEME_FALSE; + barf(C_BAD_ARGUMENT_TYPE_NO_SYMBOL_ERROR, NULL, sym); + } for(stp = symbol_table_list; stp != NULL; stp = stp->next) { bucket = lookup_bucket(sym, stp); -- 2.11.0
signature.asc
Description: PGP signature
_______________________________________________ Chicken-hackers mailing list [email protected] https://lists.nongnu.org/mailman/listinfo/chicken-hackers
