Well just a last thing i wanted to mention with struct, but i know you already know most of this stuff, but it's just because you asked the reason why it's better than structures etc
But if i have to really explain all my hollistic reasoning, it would take a whole book, because it's system that is originally bootable and can run on bare metal, so there are many aspect i designed coming from ActiveX and web browser, and problematics of video streaming, interfacing, data format, p2p web 2.0, javascript, DOM etc
But the really first motivation for doing the tree thing instead of C structure, is not to have to bother about pointer ownsership and data translation.
Consider this
typedef struct image
{
unsigned char *data;
int width;
int height;
}
typedef struct event
{
event type;
void *data;
}
image *global_list[16];
function handle_image(image *myimage)
{
if(myimage->with<256)
global_list[n]=myimage;
}
function event_handler(event *myevent)
{
image *myimage;
if(myevent->type==image_event)
handle_image((image *)myevent->image);
}
Well simple case, but the question is do you need to free the event data after the call to the event_handler or not.
Without reference counter you can't know.
If you free it, you might end with an unallocated pointer in the global_image_list, or worst, a pointer to something else, without having anyway to detect this.
If you don't free it and it's not copied, you end up with a memory leak ( allocated memory without any valid pointer to it in the program data).
Same if you need to reallocate the pointer.
The main motivation is this, so you can pass generic reference between different modules and functions, they can copy a reference of it, with lockless algorithm for reference counting so references can be shared between different threads.
Originally i just developed the json parser to be able to construct complex object hierarchy from one line and have a more 'atomic feeling' in the object construction who succeed or fail as a whole. And to have a sense of internal 'static object typing'.
And it's a very critical feature for my paradigm, because i want the design pattern to be based on asynchronous event rather than on direct function/method calls, and there is no explicit code path the compiler can easily check.
This is a must to have a single thread processing of events emitted by asynchronous sources, and to have the 'green threaded' feeling on high level, even with C, and for most simple case the green thread can keep locklessly synchronized with other heavy threads or interrupts.
And the other motivation is with interfacing and data serialization / jsonification , binary compatibility etc.
If you start from C struct, you need 4 functions around each structure you want to serialize or share, 1 to serialize, 1 to deserialize, 1 to jsoninify, 1 to dejonisfy.
With code spread in many different part, away from the 'hot code' where the real work on the data take place.
With this system, you can just add a member to the structure in the 'hot code', in the code that actually produce the data, and then it will be automatically serialized or jsonified with the new member. Without you have a single line of code to change anywhere else. Even if that involve some boilerblate in the 'hot code'.
Even if this policy with rpc mean that caller define data format of the input, and callee the data format of the output, even if they can be in different language. But it seem more logical and more efficient from a programmer perspective.
But after well it's still C code, so you can use all the dirty C stuff, binary packed structures, cheap cast, inline assembler, stack manipulation, and screw up everything and end with 0day exploits every day.
Or you can use the boilerplate and having no buffer overflow, automatic conversion to/from json and binary, lockless reference counting, and multi thread safety on manipulation of array and lists.
Most of the time, cpu cache and instruction pipelining will do a much better job at dealing with problem either it's concurrent access, or caching, with instruction re odering, most modern cpu have complex instruction pipeline who can do the job at runtime much better than any compiler, and the last generation cpu and motherboard / north bridge/ south bridge etc have good handling of SMP with data shared between core, caches, and north-south bridges, with atomic operations etc.
My dream would have to get to green thread in C from bare metal interupt And i'm not too far actually lol
I hope it's not too long
I'm trying to be succint, i think it's the last very long thing i need to explain for the moment anyway
And i know you already know most of the stuff and you already discussed them for month with sean
But its to explain my side
I started to code on the script parser too, i'll try to get something working in some days