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

Reply via email to