I wrote about it last week, but already that post is growing out of date. Here's an initial sketch.
So far all that works is function definitions with no arguments or body. They emit just the prologue and epilogue code sequences.
But I have a sketch of the next few steps of the design in there.
The design has changed in 2 ways.
#1: no more uninitialized variables. There's just no safe way to avoid initialization when structs can contain pointers.
This adds overheads to local variables in two ways: performance, and translator complexity for length-prefixed arrays. We can't just zero out everything, we also have to write array lengths in. Since structs may contain arrays, initializing a variable may involve writing lengths to multiple locations.
#2: unwinding the stack when exiting a scope. I can't just increment the stack pointer, I need to also restore any necessary registers along the way.
Another complication is that I need Java's labeled break
s. Since break
does double-duty for both conditionals and loops, it's too onerous to only be able to break
out of one scope at a time. But labeled break
s increase the frequency with which I need to unwind the stack. More overhead.
The common theme here seems to be that the translator needs to maintain 'symbolic' representations of contiguous memory regions, tracking either values or register bindings for offsets.
I'm not sure how I feel about these choices. Perhaps I should give up on this whole design and switch to something more traditional. A memory-safe C-like language. So I'd love to hear feedback and suggestions.
This post is part of my Freewheeling Apps Devlog.
Comments gratefully appreciated. Please send them to me by any method of your choice and I'll include them here.