Daily Warmup Sketches 1: Generic Catgirl
Posted: 2022-04-20
Posted: 2022-04-20
Fixed one more Ninkasi bug today!
Functions in Ninkasi have three undocumented variables. Named function arguments just refer to stack positions relative to the current stack frame, so it was pretty simple to add variables that refer to the function ID itself, the return pointer, and the argument count, because all of these values exist on the stack just like the arguments to the function itself.
These are considered debugging-only features, but they should at least be not-broken debugging-only features.
These variables are:
_functionId
- The function being called. This can be called as a
function, itself. There are a few things to watch out for with it,
however. If used with callable objects, the value will be the
object and not the function. This is because the 'call'
instruction accepts that object as its function argument and
then alters the argument list and argument count.
_argumentCount
- The number of arguments. This will include the
object's _data
field when usedwith a callable object, which will
be different from the actual argument count from the call. This
is less useful because Ninkasi does not (yet) support varargs
function calls for functions defined in the scripting system
though it someday could. Altering this will likely cause stack
corruption.
_returnPointer
- The instruction pointer to return to when the
"return" instruction executes. Not super useful from a scripting
standpoint, unless you want some insight about the caller. If you
want to live dangerously, you can even alter it before returning!
(But I don't recommend it. Will also cause stack corruption,
probably.)
At some point along the way, I had designed the 'call' instruction to expect a stack that looked like this (example 3-parameter function):
index | value | type
---------------------------------
-6 | ... |
-5 | arg0 | any type
-4 | arg1 | any type
-3 | arg2 | any type
-2 | _functionId | function
-1 | _argumentCount | integer
Later down the road, I had to change it to this:
index | value | type
---------------------------------
-6 | ... |
-5 | _functionId | function
-4 | arg0 | any type
-3 | arg1 | any type
-2 | arg2 | any type
-1 | _argumentCount | integer
I'm not sure off the top of my head why I had to do this, but my guess is that it was simply the order that arguments needed to be evaluated and then pushed onto the stack.
Anyway, when I made this change, I apparently forgot to update the
position of _functionId
. The arguments still needed a +1 offset in
the stack that I always considered a sort of mystery. Well, the +1
offset was to skip the _functionId
, and the functionId
was
pointing to one of the arguments.
This was a pretty simple fix. Just remove the offset, and move the
_functionId
setup code to before the argument setup loop.
Sometimes it really is that easy!
Posted: 2021-09-06
Started a new D&D game, so that means new lamia art!
Posted: 2021-09-05
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 [ 53 ] 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92