A year or so ago , inspired by Igor Stasenko’s excellent work on NativeBoost in Squeak/Pharo, I did a ‘native’ package for Self. This added a new _RunNativeWith: primitive used roughly like this;
machineCodeInByteVector _RunNativeWith: someByteVector With: anotherByteVector
This worked fairly well but I realised it had two main problems. Firstly the garbage collection kept on moving the machineCodeInByteVector around. This meant that before we ran the code, we would have to remark it as executable, requiring a kernel call on each run. Secondly, keeping everything in byteVectors didn’t sit well with the existing ‘proxy’ tools.
I’ve now pushed my second try at this to the ‘native2’ branch on Github. It is a handful of new primitives on proxy and fctProxy, which can be used roughly as;
| p |
p: fctProxy _AllocateBytes: 1000.
“the proxy now points to a mmap-ed region of memory”
p _LoadByteVector: machineCode AtOffset: 0.
“copy across our compiled function”
p _RunNativeWith: aByteVector Type: 0 With: aProxy Type: 1.
“run. We have to tell the VM whether we’re passing it a byteVector or proxy, unfortunately. "
As before, the machineCode is a compiled c function in the form:
void fct(char*, char* …)
There is a Self method which will take a short bit of c code, compile is and put in a byteVector for you, assuming you have cc on your system.
All the primitives have IfFail: alternatives which should preferably be used.
What’s missing is callbacks. I’m not sure how to do them, so if you have ideas then I’l be interested to hear them! I’m looking for something very simple and flexible so complexity can be kept on the Self side of things.
Keep having fun,