Igor Stasenko wrote:
There are already some steps done in this direction. A sources for RISC architecture generate a foo struct , which holds all interpreter globals. Also, i did some changes in Exupery to create a single struct of all VM globals (not only variables, but functions too). This was done to make it easier to get address of any global symbol what Exupery needs. I'm also experimented to replace all direct calls to function to indirect (i.e. foo->primAdd(x,y) instead of primAdd(x,y)). This caused about ~1% of speed degradation in tinyBenchmarks :)
Ah, indeed, I forgot about that.
Also, moving forward on this renders an InterpreterProxy struct useless, because we can just pass an address to our 'foo' struct to plugins which already contains everything what plugin can reach.
But this isn't quite true. One of the reasons for the proxy is to abstract from the actual implementation since C doesn't do proper name lookup for names but rather uses indexes. And so, if you happen to add or remove a method from that struct, your plugins will be screwed ;-)
The above takes care about the interpreter but there are still primitives and plugins that need to be dealt with. What I would do here is define operations like ioLock(struct VM) and ioUnlock(struct VM) that are the effective equivalent of Python's GIL (global interpreter lock) and allow exclusive access to primitives that have not been converted to multi-threading yet. How exactly this conversion should happen is deliberately left open here; maybe changing the VMs major proxy version is the right thing to do to indicate the changed semantics. In any case, the GIL allows us to readily reuse all existing plugins without having to worry about conversion early on.
Or as i proposed in earlier posts, the other way could be to schedule all primitive calls, which currently don't support multi-threading to single 'main' thread. Then we don't need the GIL.
I had missed that. Yes, that would work just as well.
Cheers, - Andreas