shithub: femtolisp

Download patch

ref: 271cf34e9911bc44c7dd0777c7ad4491d3a9580b
parent: 6bf5aa0c7267b00628125b0c174c391ca9db5287
author: JeffBezanson <jeff.bezanson@gmail.com>
date: Tue May 4 14:17:55 EDT 2010

some critical bug fixes


--- a/femtolisp/cvalues.c
+++ b/femtolisp/cvalues.c
@@ -121,6 +121,8 @@
 
 static value_t cprim(fltype_t *type, size_t sz)
 {
+    assert(!ismanaged((uptrint_t)type));
+    assert(sz == type->size);
     cprim_t *pcp = (cprim_t*)alloc_words(CPRIM_NWORDS-1+NWORDS(sz));
     pcp->type = type;
     return tagptr(pcp, TAG_CPRIM);
@@ -412,6 +414,7 @@
     sz = elsize * cnt;
 
     if (isvector(arg)) {
+        assert(cnt <= vector_size(arg));
         for(i=0; i < cnt; i++) {
             cvalue_init(eltype, vector_elt(arg,i), dest);
             dest += elsize;
--- a/femtolisp/flisp.boot
+++ b/femtolisp/flisp.boot
@@ -1,34 +1,32 @@
 (*banner* ";  _\n; |_ _ _ |_ _ |  . _ _\n; | (-||||_(_)|__|_)|_)\n;-------------------|----------------------------------------------------------\n\n"
 	  *interactive* #f *syntax-environment*
-	  #table(with-bindings #fn(">000s1c0qe1c2|32e1e3|32e1c4|3243;" [#fn("A000r3e0c1L1e2c3g2|33L1e4e2c5|}3331c6c7e4\x7f31Kc7e4e2c8|g23331KL3L144;" [nconc
-  let map #.list copy-list #fn("8000r2c0|}L3;" [set!]) unwind-protect begin #fn("8000r2c0|}L3;" [set!])])
-  map #.car cadr #fn("6000r1e040;" [gensym])])  letrec #fn(">000s1e0c1L1e2c3|32L1e2c4|32e5}3134e2c6|32K;" [nconc
-  lambda map #.car #fn("8000r1c0e1|31K;" [set! copy-list]) copy-list #fn("6000r1e040;" [void])])  assert #fn("<000r1c0|]c1c2c3|L2L2L2L4;" [if
-  raise quote assert-failed])  label #fn(":000r2c0|L1c1|}L3L3^L2;" [lambda set!])  do #fn("A000s2c0qe130}Me2c3|32e2e4|32e2c5|3245;" [#fn("A000r5c0|c1g2c2}c3e4\x7fN31Ke5c3L1e4i0231|g4KL133L4L3L2L1|g3KL3;" [letrec
-  lambda if begin copy-list nconc]) gensym map #.car cadr #fn("7000r1e0|31F680e1|41;|M;" [cddr
-  caddr])])  quasiquote #fn("7000r1e0|41;" [bq-process])  when #fn("<000s1c0|c1}K^L4;" [if
-  begin])  with-input-from #fn("=000s1e0c1L1c2|L2L1L1e3}3143;" [nconc
-								with-bindings
-								*input-stream*
-								copy-list])  dotimes #fn(";000s1c0q|M|\x8442;" [#fn("=000r2c0`c1}aL3e2c3L1|L1L1e4\x7f3133L4;" [for
+	  #table(letrec #fn(">000s1e0c1L1e2c3|32L1e2c4|32e5}3134e2c6|32K;" [nconc
+  lambda map #.car #fn("8000r1c0e1|31K;" [set! copy-list]) copy-list #fn("6000r1e040;" [void])])  quasiquote #fn("7000r1e0|41;" [bq-process])  when #fn("<000s1c0|c1}K^L4;" [if
+  begin])  dotimes #fn(";000s1c0q|M|\x8442;" [#fn("=000r2c0`c1}aL3e2c3L1|L1L1e4\x7f3133L4;" [for
   - nconc lambda copy-list])])  unwind-protect #fn("8000r2c0qe130e13042;" [#fn("@000r2c0}c1_\x7fL3L2L1c2c3~c1|L1c4}L1c5|L2L3L3L3}L1L3L3;" [let
   lambda prog1 trycatch begin raise]) gensym])  define-macro #fn("?000s1c0c1|ML2e2c3L1|NL1e4}3133L3;" [set-syntax!
   quote nconc lambda copy-list])  receive #fn("@000s2c0c1_}L3e2c1L1|L1e3g23133L3;" [call-with-values
-  lambda nconc copy-list])  unless #fn("=000s1c0|^c1}KL4;" [if begin])  let #fn(":000s1c0q^41;" [#fn("<000r1~C6D0~m02\x7fMo002\x7fNo01530]2c0qe1c2L1e3c4~32L1e5\x7f3133e3c6~3242;" [#fn("8000r2~6;0c0~|L3530|}K;" [label])
+  lambda nconc copy-list])  unless #fn("=000s1c0|^c1}KL4;" [if begin])  let* #fn("A000s1|?6E0e0c1L1_L1e2}3133L1;e0c1L1e3|31L1L1e2|NF6H0e0c4L1|NL1e2}3133L1530}3133e5|31L2;" [nconc
+  lambda copy-list caar let* cadar])  case #fn(":000s1c0q]41;" [#fn("7000r1c0m02c1qe23041;" [#fn("9000r2}c0\x8250c0;}\x8540^;}C6=0c1|e2}31L3;}?6=0c3|e2}31L3;}N\x85>0c3|e2}M31L3;e4c5}326=0c6|c7}L2L3;c8|c7}L2L3;" [else
+  eq? quote-value eqv? every #.symbol? memq quote memv] vals->cond)
+  #fn(";000r1c0|i10L2L1c1e2c3qi1132KL3;" [let cond map #fn("8000r1i10~|M32|NK;" [])])
+  gensym])])  catch #fn("7000r2c0qe13041;" [#fn("@000r1c0\x7fc1|L1c2c3c4|L2c5c6|L2c7c8L2L3c5c9|L2~L3L4c:|L2c;|L2L4L3L3;" [trycatch
+  lambda if and pair? eq car quote thrown-value cadr caddr raise]) gensym])  assert #fn("<000r1c0|]c1c2c3|L2L2L2L4;" [if
+  raise quote assert-failed])  label #fn(":000r2c0|L1c1|}L3L3^L2;" [lambda set!])  do #fn("A000s2c0qe130}Me2c3|32e2e4|32e2c5|3245;" [#fn("A000r5c0|c1g2c2}c3e4\x7fN31Ke5c3L1e4i0231|g4KL133L4L3L2L1|g3KL3;" [letrec
+  lambda if begin copy-list nconc]) gensym map #.car cadr #fn("7000r1e0|31F680e1|41;|M;" [cddr
+  caddr])])  with-input-from #fn("=000s1e0c1L1c2|L2L1L1e3}3143;" [nconc
+								  with-bindings
+								  *input-stream*
+								  copy-list])  let #fn(":000s1c0q^41;" [#fn("<000r1~C6D0~m02\x7fMo002\x7fNo01530]2c0qe1c2L1e3c4~32L1e5\x7f3133e3c6~3242;" [#fn("8000r2~6;0c0~|L3530|}K;" [label])
   nconc lambda map #fn("6000r1|F650|M;|;" []) copy-list #fn("6000r1|F650|\x84;e040;" [void])])])  cond #fn("9000s0c0q]41;" [#fn("7000r1c0qm02|~41;" [#fn("7000r1|?640^;c0q|M41;" [#fn(":000r1|Mc0<17702|M]<6@0|N\x8550|M;c1|NK;|N\x85@0c2|Mi10~N31L3;|\x84c3\x82W0e4e5|31316A0c6qe7e5|313141;c8qe93041;c:|Mc1|NKi10~N31L4;" [else
   begin or => 1arg-lambda? caddr #fn("=000r1c0|~ML2L1c1|c2e3e4~3131Ki20i10N31L4L3;" [let
   if begin cddr caddr]) caadr #fn("<000r1c0|~ML2L1c1|e2~31|L2i20i10N31L4L3;" [let
   if caddr]) gensym if])] cond-clauses->if)])])  throw #fn(":000r2c0c1c2c3L2|}L4L2;" [raise
   list quote thrown-value])  time #fn("7000r1c0qe13041;" [#fn(">000r1c0|c1L1L2L1c2~c3c4c5c1L1|L3c6L4L3L3;" [let
-  time.now prog1 princ "Elapsed time: " - " seconds\n"]) gensym])  let* #fn("A000s1|?6E0e0c1L1_L1e2}3133L1;e0c1L1e3|31L1L1e2|NF6H0e0c4L1|NL1e2}3133L1530}3133e5|31L2;" [nconc
-  lambda copy-list caar let* cadar])  case #fn(":000s1c0q]41;" [#fn("7000r1c0m02c1qe23041;" [#fn("9000r2}c0\x8250c0;}\x8540^;}C6=0c1|e2}31L3;}?6=0c3|e2}31L3;}N\x85>0c3|e2}M31L3;e4c5}326=0c6|c7}L2L3;c8|c7}L2L3;" [else
-  eq? quote-value eqv? every #.symbol? memq quote memv] vals->cond)
-  #fn(";000r1c0|i10L2L1c1e2c3qi1132KL3;" [let cond map #fn("8000r1i10~|M32|NK;" [])])
-  gensym])])  with-output-to #fn("=000s1e0c1L1c2|L2L1L1e3}3143;" [nconc
-								  with-bindings
-								  *output-stream*
-								  copy-list])  catch #fn("7000r2c0qe13041;" [#fn("@000r1c0\x7fc1|L1c2c3c4|L2c5c6|L2c7c8L2L3c5c9|L2~L3L4c:|L2c;|L2L4L3L3;" [trycatch
-  lambda if and pair? eq car quote thrown-value cadr caddr raise]) gensym]))
+  time.now prog1 princ "Elapsed time: " - " seconds\n"]) gensym])  with-output-to #fn("=000s1e0c1L1c2|L2L1L1e3}3143;" [nconc
+  with-bindings *output-stream* copy-list])  with-bindings #fn(">000s1c0qe1c2|32e1e3|32e1c4|3243;" [#fn("A000r3e0c1L1e2c3g2|33L1e4e2c5|}3331c6c7e4\x7f31Kc7e4e2c8|g23331KL3L144;" [nconc
+  let map #.list copy-list #fn("8000r2c0|}L3;" [set!]) unwind-protect begin #fn("8000r2c0|}L3;" [set!])])
+  map #.car cadr #fn("6000r1e040;" [gensym])]))
 	  *whitespace* "\t\n\v\f\r \u0085  ᠎           \u2028\u2029   " 1+
 	  #fn("7000r1|aw;" [] 1+) 1- #fn("7000r1|ax;" [] 1-) 1arg-lambda?
 	  #fn("8000r1|F16T02|Mc0<16J02|NF16B02|\x84F16:02e1|\x84a42;" [lambda
@@ -79,7 +77,7 @@
 	  cadar #fn("6000r1|M\x84;" [] cadar) caddar
 	  #fn("6000r1|MN\x84;" [] caddar) cadddr #fn("6000r1|NN\x84;" [] cadddr)
 	  caddr #fn("6000r1|N\x84;" [] caddr) cadr
-	  #fn("6000r1|\x84;" [] cadr) call-with-values #fn("7000r2c0q|3041;" [#fn("7000r1|F16902i10|M<680\x7f|Nv2;\x7f|41;" [])] #3=[(*values*)
+	  #fn("6000r1|\x84;" [] cadr) call-with-values #fn("7000r2c0q|3041;" [#fn("7000r1|F16902i10|M<680\x7f|Nv2;\x7f|41;" [])] #2=[(*values*)
   ()])
 	  cdaaar #fn("6000r1|MMMN;" [] cdaaar) cdaadr
 	  #fn("6000r1|\x84MN;" [] cdaadr) cdaar #fn("6000r1|MMN;" [] cdaar)
@@ -340,11 +338,11 @@
 	  #fn("9000r1e0c1_|43;" [foldl #.cons] reverse) reverse! #fn("7000r1c0q_41;" [#fn("9000r1]~F6C02~N~|~m02P2o005\x1c/2|;" [])] reverse!)
 	  self-evaluating? #fn("8000r1|?16602|C@17K02e0|3116A02|C16:02|e1|31<;" [constant?
   top-level-value] self-evaluating?)
-	  separate #fn(":000r2~|}__44;" [] #2=[#fn(";000r4}\x8580g2g3K;|}M316@0~|}N}Mg2Kg344;~|}Ng2}Mg3K44;" [] #2#)
-					       ()])
+	  separate #fn("7000r2c0q]41;" [#fn(":000r1c0qm02|~\x7f__44;" [#fn(";000r4}\x85;0e0g2g342;|}M316@0~|}N}Mg2Kg344;~|}Ng2}Mg3K44;" [values] separate-)])] separate)
 	  set-syntax! #fn("9000r2e0e1|}43;" [put! *syntax-environment*] set-syntax!)
-	  simple-sort #fn("7000r1|A17602|NA640|;c0q|M41;" [#fn("9000r1c0qe1c2q~N3241;" [#fn(":000r1e0e1|M31~L1e1|N3143;" [nconc
-  simple-sort]) separate #fn("7000r1|~X;" [])])] simple-sort)
+	  simple-sort #fn("7000r1|A17602|NA640|;c0q|M41;" [#fn("8000r1e0c1qc2q42;" [call-with-values
+  #fn("8000r0e0c1qi10N42;" [separate #fn("7000r1|~X;" [])])
+  #fn(":000r2e0e1|31~L1e1}3143;" [nconc simple-sort])])] simple-sort)
 	  string.join #fn("7000r2|\x8550c0;c1qe23041;" ["" #fn("8000r1e0|~M322e1c2q~N322e3|41;" [io.write
   for-each #fn("8000r1e0~i11322e0~|42;" [io.write]) io.tostring!]) buffer] string.join)
 	  string.lpad #fn(";000r3e0e1g2}e2|31x32|42;" [string string.rep
@@ -382,7 +380,7 @@
   x newline #.apply]) ()])
 	  untrace #fn("8000r1c0qe1|3141;" [#fn("9000r1e0|316@0e1~e2|31b2[42;];" [traced?
   set-top-level-value! function:vals]) top-level-value] untrace)
-	  values #fn("9000s0|F16602|NA650|M;~|K;" [] #3#) vector->list
+	  values #fn("9000s0|F16602|NA650|M;~|K;" [] #2#) vector->list
 	  #fn("8000r1c0qe1|31_42;" [#fn(":000r2a|c0qu2};" [#fn("8000r1i10~|x[\x7fKo01;" [])])
 				    length] vector->list)
 	  vector.map #fn("8000r2c0qe1}3141;" [#fn("8000r1c0qe1|3141;" [#fn(":000r1`~axc0qu2|;" [#fn(":000r1~|i20i21|[31\\;" [])])
--- a/femtolisp/flisp.c
+++ b/femtolisp/flisp.c
@@ -487,6 +487,7 @@
         nfn->env = relocate(fn->env);
         nfn->vals = relocate(nfn->vals);
         nfn->bcode = relocate(nfn->bcode);
+        assert(!ismanaged(fn->name));
         nfn->name = fn->name;
         return nc;
     }
@@ -553,10 +554,17 @@
     relocate_typetable();
     rs = readstate;
     while (rs) {
-        for(i=0; i < rs->backrefs.size; i++)
-            rs->backrefs.table[i] = (void*)relocate((value_t)rs->backrefs.table[i]);
-        for(i=0; i < rs->gensyms.size; i++)
-            rs->gensyms.table[i] = (void*)relocate((value_t)rs->gensyms.table[i]);
+        value_t ent;
+        for(i=0; i < rs->backrefs.size; i++) {
+            ent = (value_t)rs->backrefs.table[i];
+            if (ent != HT_NOTFOUND)
+                rs->backrefs.table[i] = (void*)relocate(ent);
+        }
+        for(i=0; i < rs->gensyms.size; i++) {
+            ent = (value_t)rs->gensyms.table[i];
+            if (ent != HT_NOTFOUND)
+                rs->gensyms.table[i] = (void*)relocate(ent);
+        }
         rs->source = relocate(rs->source);
         rs = rs->prev;
     }
@@ -1697,6 +1705,7 @@
             v = Stack[bp+nargs];
             while (s--)
                 v = vector_elt(v, vector_size(v)-1);
+            assert(i < vector_size(v));
             vector_elt(v, i) = Stack[SP-1];
             NEXT_OP;
 
--- a/femtolisp/flisp.h
+++ b/femtolisp/flisp.h
@@ -75,7 +75,7 @@
 #define vector_size(v) (((size_t*)ptr(v))[0]>>2)
 #define vector_setsize(v,n) (((size_t*)ptr(v))[0] = ((n)<<2))
 #define vector_elt(v,i) (((value_t*)ptr(v))[1+(i)])
-#define vector_grow_amt(x) ((x)<8 ? 4 : 6*((x)>>3))
+#define vector_grow_amt(x) ((x)<8 ? 5 : 6*((x)>>3))
 // functions ending in _ are unsafe, faster versions
 #define car_(v) (((cons_t*)ptr(v))->car)
 #define cdr_(v) (((cons_t*)ptr(v))->cdr)
--- a/femtolisp/flmain.c
+++ b/femtolisp/flmain.c
@@ -18,7 +18,7 @@
 static value_t argv_list(int argc, char *argv[])
 {
     int i;
-    value_t lst, temp;
+    value_t lst=FL_NIL, temp;
     fl_gc_handle(&lst);
     fl_gc_handle(&temp);
     for(i=argc-1; i >= 0; i--) {
--- a/femtolisp/read.c
+++ b/femtolisp/read.c
@@ -377,6 +377,7 @@
     size_t i, s = vector_size(v);
     size_t d = vector_grow_amt(s);
     PUSH(v);
+    assert(s+d > s);
     value_t newv = alloc_vector(s+d, 1);
     v = Stack[SP-1];
     for(i=0; i < s; i++)
@@ -408,6 +409,7 @@
         }
         elt = do_read_sexpr(UNBOUND);
         v = Stack[SP-1];
+        assert(i < vector_size(v));
         vector_elt(v,i) = elt;
         i++;
     }
@@ -521,7 +523,7 @@
         }
         *pc = c;
         c = do_read_sexpr(UNBOUND); // must be on separate lines due to
-        car_(*pc) = c;                // undefined evaluation order
+        car_(*pc) = c;              // undefined evaluation order
 
         t = peek();
         if (t == TOK_DOT) {
@@ -666,9 +668,11 @@
     state.source = f;
     readstate = &state;
     assert(toktype == TOK_NONE);
+    fl_gc_handle(&tokval);
 
     v = do_read_sexpr(UNBOUND);
 
+    fl_free_gc_handles(1);
     readstate = state.prev;
     free_readstate(&state);
     return v;