I found another obscure optimiser (probably) bug. Unlike my last report I'm not including a second problem that's really caused by me not paying attention.
I've tested it on the s7 I pulled this morning (76c6f2b). Given this C function: static s7_pointer _wtf (s7_scheme *sc, s7_pointer args) { return s7_values(sc, s7_list(sc, 2, s7_make_integer(sc, 42), s7_make_integer(sc, 84))); } Installed by this cargo-culty macro: #define K7_DEFINE_FUN(S,E,N,F,R,O,V,D) do { \ s7_pointer _sym = s7_make_symbol((S), (N)); \ s7_pointer _fun = s7_make_typed_function((S), (N), (F), \ (R), (O), (V), (D), NULL); \ s7_define((S), (E), _sym, _fun); \ } while (0) K7_DEFINE_FUN(sc, env, "wtf", _wtf, 0, 0, false, "(wtf)"); This happens: $ ./s7load '(define z (list (wtf))) (display z)' (42 84) $ ./s7load '(define (x) (define z (list (wtf))) (display z)) (x)' ((values 42 84)) The list must be longer than 1 and the C function called within a lisp function, but not in a bare lambda: $ ./s7load '((lambda () (define z (list (wtf))) (display z)))' (42 84) Matthew ps. I've included below some of the patches I apply on top of S7 whenever I pull the latest release which you may want to consider, particularly the last one which corrects broken (but harmless) code. No need to fill in a buffer if its contents are about to be replaced (this change was made when I would have had to malloc a large buffer just to pass it into this function where its contents would then be ignored twice). @@ -9271,7 +9271,8 @@ static Inline s7_pointer inline_make_string_with_length(s7_scheme *sc, const cha new_cell(sc, new_string, T_STRING | T_SAFE_PROCEDURE); string_block(new_string) = inline_mallocate(sc, len + 1); string_value(new_string) = (char *)block_data(string_block(new_string)); - memcpy((void *)string_value(new_string), (const void *)str, len); + if (str) + memcpy((void *)string_value(new_string), (const void *)str, len); string_value(new_string)[len] = 0; string_length(new_string) = len; string_hash(new_string) = 0; Slightly simpler/prettier calling convention for this function and those which use it. @@ -31972,7 +31977,9 @@ s7_pointer s7_load_c_string_with_environment(s7_scheme *sc, const char *content, declare_jump_info(); TRACK(sc); - if (content[bytes] != 0) + if (bytes == 0) + bytes = strlen(content); + else if (content[bytes] != 0) error_nr(sc, make_symbol(sc, "bad-data", 8), set_elist_1(sc, wrap_string(sc, "s7_load_c_string content is not null terminated", 47))); port = open_input_string(sc, content, bytes); port_loc = gc_protect_1(sc, port); Zero is used in other parts of the code that create hash tables so why not make-hash-table, and it tests for 0 later to sanitise it. @@ -46626,7 +46633,7 @@ in the table; it is a cons, defaulting to (cons #t #t) which means any types are if (!s7_is_integer(len)) return(method_or_bust(sc, len, caller, args, sc->type_names[T_INTEGER], 1)); size = s7_integer_clamped_if_gmp(sc, len); - if (size <= 0) /* we need s7_int here to catch (make-hash-table most-negative-fixnum) etc */ + if (size < 0) /* we need s7_int here to catch (make-hash-table most-negative-fixnum) etc */ out_of_range_error_nr(sc, caller, int_one, len, wrap_string(sc, "it should be a positive integer", 31)); if ((size > sc->max_vector_length) || (size >= (1LL << 32))) /* s7test tests >= */ Compiler complains. @@ -79775,7 +79793,7 @@ static Inline void inline_op_let_a_old(s7_scheme *sc) /* tset(2) fb(0) cb(4) le set_curlet(sc, let); } -static inline void op_let_a_old(s7_scheme *sc) {return(inline_op_let_a_old(sc));} +static inline void op_let_a_old(s7_scheme *sc) {inline_op_let_a_old(sc);} static void op_let_a_a_new(s7_scheme *sc) { _______________________________________________ Cmdist mailing list Cmdist@ccrma.stanford.edu https://cm-mail.stanford.edu/mailman/listinfo/cmdist