2023-10-03 14:45:12 +02:00
|
|
|
/**************************************************************
|
|
|
|
_ __ _ _
|
|
|
|
_ __ ___| |_ _ __ ___ / _| ___ _ __| |_| |__
|
|
|
|
| '__/ _ \ __| '__/ _ \| |_ / _ \| '__| __| '_ \
|
|
|
|
| | | __/ |_| | | (_) | _| (_) | | | |_| | | |
|
|
|
|
|_| \___|\__|_| \___/|_| \___/|_| \__|_| |_|
|
|
|
|
for nga
|
2023-03-29 02:20:33 +02:00
|
|
|
|
2023-10-03 14:45:12 +02:00
|
|
|
(c) Charles Childers, Luke Parrish, Marc Simpsonn,
|
|
|
|
Jay Skeer, Kenneth Keating
|
|
|
|
|
|
|
|
**************************************************************/
|
2023-03-29 02:20:33 +02:00
|
|
|
|
|
|
|
|
|
|
|
#ifdef ENABLE_FFI
|
|
|
|
#include <dlfcn.h>
|
|
|
|
|
|
|
|
typedef void (*External)(void *);
|
|
|
|
|
|
|
|
void *handles[32];
|
|
|
|
External funcs[32000];
|
|
|
|
int nlibs, nffi;
|
|
|
|
|
|
|
|
void open_library(NgaState *vm) {
|
|
|
|
handles[nlibs] = dlopen(string_extract(vm, stack_pop(vm)), RTLD_LAZY);
|
|
|
|
stack_push(vm, nlibs);
|
|
|
|
nlibs++;
|
|
|
|
}
|
|
|
|
|
|
|
|
void map_symbol(NgaState *vm) {
|
|
|
|
int h;
|
|
|
|
h = stack_pop(vm);
|
|
|
|
char *s = string_extract(vm, stack_pop(vm));
|
|
|
|
funcs[nffi] = dlsym(handles[h], s);
|
|
|
|
stack_push(vm, nffi);
|
|
|
|
nffi++;
|
|
|
|
}
|
|
|
|
|
|
|
|
void invoke(NgaState *vm) {
|
|
|
|
funcs[stack_pop(vm)](vm);
|
|
|
|
}
|
|
|
|
|
|
|
|
void io_ffi(NgaState *vm) {
|
|
|
|
switch (stack_pop(vm)) {
|
|
|
|
case 0: open_library(vm); break;
|
|
|
|
case 1: map_symbol(vm); break;
|
|
|
|
case 2: invoke(vm); break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void query_ffi(NgaState *vm) {
|
|
|
|
stack_push(vm, 0);
|
2023-12-09 19:15:54 +01:00
|
|
|
stack_push(vm, DEVICE_FFI);
|
2023-03-29 02:20:33 +02:00
|
|
|
}
|
|
|
|
#endif
|