The idea is to find th def that contains the address. Had to write my
own bsearch (well... lifted from wikipedia) because libc's is exact. The
defs are assumed to be sorted (which qfcc now ensures when it writes
progs and sym files).
Type encodings are used whenever they are available. For now, if they
are not, then everything is treated as void (which prints <void>, not
very useful). Most return statements and references to .return are now
very readable (excluding structs), and only params going through "..."
are a messy union.
The memset instructions now match the move* instructions other than the
first operand (always int). Probably breaks much, but fixed in next few
commits.
This returns the character (as an int) at the index. Equivalent to
string[index], but qc code doesn't have char-level access and not having
it means that strings can internally change to wchar without too much
fuss (maybe).
If a temp string is found in the return slot, PR_FreeTempStrings won't
delete the string. However, PR_PopFrame was blindly stomping on the
possibly surviving temp string with the push strings, which would cause
a leak.
This causes the block to be freed when the forward: handler returns
(assuming it's not yet another builtin). This is necessary so calling a
lot of forwarded messages in a loop doesn't leak memory (though it will
get freed eventually).
This "pushes" a temp string onto the callee's stack frame after removing
it from the caller's stack frame. This is so builtins can pass
auto-freed memory to called progs code. No checking is done, but mayhem
is likely to ensue if a string is pushed that was allocated in an
earlier frame.
With this, object's implementing forward:: seem to accept the message
well, including receiving all the original args (not quite sure how to
deal with them in ruamoko code just yet, though).
PR_AllocTempBlock() works the same way as PR_SetTempString(), except
that it takes a size parameter and always allocates (never tries to
merge). This is, in a way, abusing the string system, but I needed a way
to allocate a block of progs memory that would be automatically freed
when the current frame ended. The biggest abuse is the need to cast away
the const of PR_GetString()'s return value.
libr supplies an __obj_forward definition that links to a builtin, but
as it is the only def in its object file, it is readily replaceable by
an alternative Ruamoko implementation.
The builtin version currently simply errors out (rather facetiously),
but only as a stub to allow progs to load.
This should speed up ruamoko code somewhat as hash table lookups have
been replaced with direct array indexing. As a bonus, support for
message forwarding has been added (though not tested).
Move the semi-permanent resource initialisation into the module init and
the cleanup of those resources into cleanup. Makes actual runtime init
much easier to read.
Rather than relying on progs code version, use the string to determine
whether PR_Sprintf should behave as if floats have been promoted through
... I imagine I'll get to the rest of the server code at some stage.
With these two changes, nq-x11 works again (teleporters were the
symptom).
This is one step closer to implementing conformsToProtocol. However,
protocols are not yet initialized correctly: they are not registered,
nor are their selectors.
While the static initializer list pointer was not written previously,
the module struct always came immediately after the symbols struct, and
the module version has so far always been 0. Thus, the list pointer is
correctly 0 for older progs and there's no need for a version bump.
With this, the VA is very close to being safe to use in a threaded
environment (so long as each VM is used by only one thread). Just the
debug file hash and source paths to sort out.
Other than consistency with printf(), I'm not sure why we went with the
printed size as the return value; returning the resultant strings makes
much more sense as dsprintf() (etc) can then be used as a safe va()