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
[email protected]
https://cm-mail.stanford.edu/mailman/listinfo/cmdist