os_claim
Jonathan Coxhead
jonathan at doves.demon.co.uk
Mon Dec 11 20:02:20 GMT 2000
| However, if you've been following UseNet recently, you'll be aware of
| the following infelicity:
|
| Presently, os_claim is prototyped as:
| os_claim( int vector, void const *routine, byte *handle );
|
| I believe this is incorrect, and should be something like
| os_claim( int vector, void (*routine)(void), byte *handle );
|
| The same problem exists for os_release, os_change_environment and its
| clients, and probably many others. I don't see any obvious way of
| persuading DefMod to generate this syntax, so it probably isn't
| possible.
It's not. :-(
The trouble is that the |routine| argument is not actually pointing at a
piece of C code: it's pointing at a piece of assembler. Though sometimes
you can call such a thing by casting the argument to a function pointer and
jumping, it's not clean because of the different calling conventions and
return mechanism. (Consider returning from a vector with/without "claiming"
it.)
(This is the exact same problem that DefMod solves, but in the other
order: calling a C function that obeys the APCS from assembler with some
given calling convention.)
In CMHG, there is a facility to declare an irq-handler. This generates a
wrapper that makes a piece of assembler (by intent, an IRQ handler, though
it works for other things too) into a "real" C function. Let's suppose that
the real code has type
void os_cmhg_handler (void *arg);
(I can't remember what it really is), so the programmer writes a function
of that type
void handler (void *arg)
{
...
}
and then the CMHG wrapper comes along and emits some code at a location
void *wrapper;
and let's call the type of that os_cmhg_wrapper.
Then a good step would be to have typedefs in OSLib
typedef void os_cmhg_handler (void *);
typedef void *os_cmhg_wrapper;
and give the prototypes as
os_error *os_claim (int vector, os_cmhg_wrapper routine,
byte *handle);
and make it clear in the documentation that you have to use CMHG to paste
the wrapper onto the handler.
Another tool could be written to do a similiar job, if CMHG is not
supported any more.
OSLib has the built-in type |.Asm| for anything that's supposed to point
to code; so it would be easy to map |.Asm| to |os_cmhg_wrapper|.
1 remaining issue springs to mind: since there are different calling
conventions for different assembler fragments---service calls, IRQ
handlers, vectors, events, pre- and post-filters, etc, it would be nice to
have a tool that generated custom veneers for each one, and for each one to
have a different type for its C function and its wrapper. So we could have
typedef bool osservice_handler (int no, ..., void *handle);
typedef void *osservice_wrapper;
Then I could write, say, my service call handler in "service.c" as
bool service (...)
{
...
}
In the CMHG file, we'd have something like
service-handler: service/service-wrapper
which generates the wrapper |service_wrapper|, and OSLib functions that
deal with service calls would have parameters of that type
(|osservice_wrapper|).
So finally, we'd need a tool that read the CMHG file, and produced a C
header file like this:
#include "os.h"
extern osservice_handler service;
extern osservice_wrapper service_wrapper;
With those extra peices, I think we'd have type-safe integration between
the various ways of hooking C code into RISC O S.
/|
o o o (_|/
/|
(_/
More information about the oslib-team
mailing list