Here's the idea. We have an RTTI object called gc_shape_t: see src/gc/flx_gc.hpp.
First we add an encode function slot to the object. Lets see what we need. If this is a simple subobject: 1. we need a pointer to the object. 2. we need a string and an offset into it to put the encoded in 3. We need pointer to the RTTI record. We can now just do 1. Calculate the size of the object from the RTTI object. 2. Ensure there is space in the string 3. Use the C++ copy constructor to put the value there. If the data type is a simple POD we can use memcpy instead of step 3. If the data type has internal pointers, we must write step 3 manually. For example, for a string we might write out the length, then the data. If the object is a whole object, there is an extra step, since a whole object is always a varray. That means there are two extra counts: the number of slots in the array and the number actually used. We must write both these numbers out first, then write out each used element, using the subroutine in the RTTI object. Now for composites. At present Felix does not have composite representation. So even though a struct, for example, consists of several components the shape descriptor only exists for the whole object. For such objects the copy constructor will still be called first, but it will just copy pointers. Now, we must do several things. First, we have to recursively copy the objects pointed at if we haven't already. We know where the pointers are from the shape. Second, we need to keep a backpatch list. This is a list of offsets of pointers we haven't copied yet. Third, we need a list of pairs: copied object address, offset in string When we find a pointer already in the list, it's already in the string, so we patch the pointer to it to be an offset into the string instead. Whenever a new whole object is put in the string, we have to check the backpatch list to see if there are some unpatched objects, of so patch them and remove from backpatch list. Actually I'm not sure we need the backpatch list if we use recursive descent, though we may end up with partially complete objects if we don't. There is a complication. Felix pointers do NOT have to point at the start of an object, in fact they can point at a C object (unknown to Felix) or be NULL. Luckily, we can convert, we just add the offset from the start of the object as well. If the object was not allocated by Felix the original pointer is left untouched. Note: some objects cannot be serialised, eg a FILE*. If we hit one, the serialisation is aborted. PROBLEMS for functions. All the above will work for functions and procedure closures correctly too. But there's a problem. Many procedures refer to the global storage object called the thread frame. And that contains pointers to the garbage collector, to standard I/O, copies of argc/argv etc. The thread frame is a standard Felix object. So we need a way to add an exclusion list, i.e. "if you find this thing don't copy it". Unfortunately the thread frame does contain global variables. This can be solved somehow, eg provide a callback to obtain a new instance of the resource. -- john skaller skal...@users.sourceforge.net http://felix-lang.org ------------------------------------------------------------------------------ Master Visual Studio, SharePoint, SQL, ASP.NET, C# 2012, HTML5, CSS, MVC, Windows 8 Apps, JavaScript and much more. Keep your skills current with LearnDevNow - 3,200 step-by-step video tutorials by Microsoft MVPs and experts. ON SALE this month only -- learn more at: http://p.sf.net/sfu/learnnow-d2d _______________________________________________ Felix-language mailing list Felix-language@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/felix-language