On 06/11/2011, at 8:46 AM, john skaller wrote: OMG .. hope I'm not premature
> > On 06/11/2011, at 8:43 AM, john skaller wrote: > >> Suspecting the code generator for the complex code in >> lib/std/posix/filesystem function >> regfilesin, I rewrote it to be a bit more procedural... discovered a bug in >> the front end >> putting a spurious label and the end of a statement match terminated by a >> wildcard >> leading to false fatal error "function doesn't return". Running the new code >> I noticed >> this: >> >> flx_ls .. '.*' >> .... >> matched .kvirc/global/defscript/theme-install.kvs >> found file .kvirc/global/defscript/toolbars.kvs >> matched .kvirc/global/defscript/toolbars.kvs >> found file .kvirc/global/help/en/_db_class.idx >> no match .kvirc/global/help/en/_db_class.idx >> .... >> >> woops! Suddenly RE2 is giving the wrong answer. >> A bit later the GC goes into spasms. The program terminates >> without error .. but fails to return ANY files. > Here's how I make a Judy Array .. study it carefully!! ///////////////////////////////// private body mkjudy = """ void **_mkjudy(FLX_APAR_DECL ::flx::gc::generic::gc_shape_t *jptr_map){ typedef void *voidp; // syntax void **m = new (*PTF gcp, *jptr_map, false) voidp; *m=0; return m; } """ ; // the "value" of a judy array is just a void* // to mutate it though, we need it to be on the heap // and use the pointer to that object as the array, // so that it can be copied about private body j1free = """ void _j1free(::flx::gc::generic::collector_t*,void *p) { //printf("Free J1Array %p\\n",p); JError_t je; Judy1FreeArray((void**)p, &je); } """ ; private type J1Array_ = "void*" requires scanner "::flx::gc::generic::Judy1_scanner", header '#include "flx_judy_scanner.hpp"', finaliser '_j1free', j1free ; _gc_pointer _gc_type J1Array_ type J1Array = "void**" requires property "needs_gc"; gen _ctor_J1Array: 1 -> J1Array = "_mkjudy(FLX_POINTER_TO_THREAD_FRAME, &@0)" requires mkjudy, property "needs_gc" ; ////////////////// and here's how I make a regex object: // hackery because ::re2::RE2 isn't copyable, so we have to use a pointer // but we need the shape of RE2 to create on the heap private type RE2_ = "::re2::RE2"; _gc_type RE2_ type RE2 = "::re2::RE2*"; gen _ctor_RE2 : string -> RE2 = "new (*PTF gcp, @0, false) RE2($1)"; ///////////// See the bug???? It's hard to see. ONE WORD BUG. Here's the right answer: _gc_pointer _gc_type RE2_ type RE2 = "::re2::RE2*"; It's so obvious now! I left out the _gc_pointer! What's that? It tells Felix an abstract type is a pointer to a Felix heap allocated objects. Here's the heap allocation: gen _ctor_RE2 : string -> RE2 = "new (*PTF gcp, @0, false) RE2($1)"; The _gc_type bit tricks Felix into believing the shape for its argument RE2_ is the shape to be used for the pointer to abstract type called RE2, so that the @0 in the "new" above is the shape of RE2_ not the shape of RE. So .. I forgot to tell Felix that an RE2 value is a pointer that needs to be scanned. So .. we made an RE2 object which is a pointer to a Felix managed heap object, and forgot to track the pointer. So .. the RE2 object appeared unreachable .. and got deleted on the first garbage collection. Clearly this either corrupted the RE2 object immediately or allowed it to be corrupted after the store got reallocated later. Here am I looking at complex C code for bugs in the GC .. bugs in Judy bugs in RE2 .. bugs in the Felix code generator ... .. and its a single missing word in the library spec :) Yeah .. and now flx_cp appears to works too! -- john skaller skal...@users.sourceforge.net ------------------------------------------------------------------------------ RSA(R) Conference 2012 Save $700 by Nov 18 Register now http://p.sf.net/sfu/rsa-sfdev2dev1 _______________________________________________ Felix-language mailing list Felix-language@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/felix-language