After getting angry at Lua for bugs reappearing after fixing them, and otherwise having issues with making it interoperable with my own language of choice (D), I decided to roll out my own VM out, with some enhanced optional features compared to regular Lua (type safety, static arrays on the stack, enhanced metatables, etc.), and also allowing the potential of other scripting languages to be ported to the VM. As I already have crafted a VM for a programmable MIDI format (M2: Docs / Implementation ; bit incomplete as of now), I thought it'll be easy, just don't optimize this time entirely around preallocation (M2 has 128 not entirely general purpose registers per pattern (musical thread) + 128 shared registers + shared arrays), add stack handling, add heap handling, add more types, etc.
Thus I begun working on PingusVM, to contribute to the problem of ever growing number of standards.
However, as time went by, I had to realize (just like every time I've added another engine feature) that it's way more complicated, especially as I have realized mid-development that I had a lot of oversight on design. Not only that, I have a lot of other projects, such as the game engine I've originally intended the VM for. My main issue is, potential candidates either lack integer support, or are very bloated (I don't need a second XML DOM parser, etc). Lua kind of worked, but after I fixed an issue (which was hard as every tutorial implied you just wanted to load a file directly instead of having the ability of loading the text directly) a very similar one reappeared, while following every tutorial possible. Others would lead me to introduce some C-style build system, as they would need "hard linking" to my engine, and that "hard linking" is why I had to halt development of my image library, as I would have needed to introduce a build system into my project for the LZW codec (required for GIF files).
Are you specifying everything beforehand? If not, I'd recommend locking in on an ISA with stack effect pre-determined. Also, minimize as much as you can.
First off: Read Xia-Feng Li's excellent book if you have not.
Then.
Here are some minimization tips I am doing for my RuppVM. I just began working on it less that 24 hours ago. But the tips are based on over 6 months of off-and-on trying to make a VM, and failing. I am sure this one will take, because of these minimization efforts:
ISA.txt
file, look at what I am doing for FFI. You don't need intricate type mappings for the FFI. Just register a 'hook' to an address in memory (or ELF).These variables are not exactly portable, but you can use them, abuse them, etc:
extern etext
-> First address past the text segment;extern edata
-> First address past the initialized data segment;extern end
-> end of bssI think there are portable libraries for handling ELFs and PEs. You could also write your own Assembly code for it. For loading functions from files, for the FFI, these help a lot.
Another aspect you should implement is a 'signal trampoline'. This trampoline will help handle signals from the OS, and hook it to your green threads.
Now, don't take these as gospel. I am sure you know most of these already. But in case there's new info, feel free to adapt it.
Star RuppVM, I will be adding a lot of stuff to it soon.
EDIT: I looked, there does not seem to be any 'portable' libraries for handling PE and ELF with the same interface. I guess ther can't be, two different beasts.
EDIT 2: The FFI could prove to be much more complex than I thought? There's libffi though.