racket-static/main_bc.c

123 lines
3.1 KiB
C
Raw Normal View History

#define MZ_PRECISE_GC
#include <racket/scheme.h>
2020-10-15 02:18:35 +00:00
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
// patchups for musl vs glibc stuff
#include <sys/stat.h>
int stat(const char *restrict path, struct stat *restrict buf) {
return __xstat(1, path, buf);
}
int fstat(int fildes, struct stat *buf) {
return __fxstat(1, fildes, buf);
}
int lstat(const char *restrict path, struct stat *restrict buf) {
return __lxstat(1, path, buf);
}
extern void* __dso_handle;
int atexit(void (*function)(void)) {
return __cxa_atexit(function, NULL, __dso_handle);
}
extern const char _binary_app_zo_start;
extern const char _binary_app_zo_end;
// ffi example call
void example_func() {
printf("hello world ffi call\n");
}
// ffi defs
typedef struct {
const char* name;
uintptr_t ptr;
} ffi_ent;
static const ffi_ent ffi_table[] = {
{"example_func", (uintptr_t) example_func}
};
static const size_t ffi_table_size = sizeof(ffi_table)/sizeof(ffi_ent);
// setup ffi table to be passed to racket
static void bc_setup_ffi_table(Scheme_Env* parent) {
Scheme_Env* mod = NULL;
Scheme_Object* table = NULL;
Scheme_Object* table_ent = NULL;
MZ_GC_DECL_REG(4);
MZ_GC_VAR_IN_REG(0, parent);
MZ_GC_VAR_IN_REG(1, mod);
MZ_GC_VAR_IN_REG(2, table);
MZ_GC_VAR_IN_REG(3, table_ent);
MZ_GC_REG();
mod = scheme_primitive_module(scheme_intern_symbol("static-ffi"), parent);
table = scheme_make_null();
for (size_t i = 0; i < ffi_table_size; i++) {
table_ent = scheme_make_null();
table_ent = scheme_make_pair(scheme_make_integer(ffi_table[i].ptr), table_ent);
table_ent = scheme_make_pair(scheme_intern_symbol(ffi_table[i].name), table_ent);
table = scheme_make_pair(table_ent, table);
}
scheme_add_global("table", table, mod);
scheme_finish_primitive_module(mod);
MZ_GC_UNREG();
}
static int run_bc(Scheme_Env* e, int argc, char* argv[]) {
(void)argc;
(void)argv;
2020-10-15 02:18:35 +00:00
volatile mz_jmp_buf* save;
mz_jmp_buf fresh;
int rv = 0;
size_t load_size = ((uintptr_t) &_binary_app_zo_end) - ((uintptr_t) &_binary_app_zo_start);
Scheme_Object* l = NULL;
Scheme_Object* a[2] = { NULL, NULL };
2020-10-15 02:18:35 +00:00
// gc setup
MZ_GC_DECL_REG(5);
MZ_GC_VAR_IN_REG(0, e);
MZ_GC_VAR_IN_REG(1, l);
MZ_GC_ARRAY_VAR_IN_REG(2, a, 2);
MZ_GC_REG();
bc_setup_ffi_table(e);
scheme_register_embedded_load(load_size, &_binary_app_zo_start);
scheme_embedded_load(load_size, &_binary_app_zo_start, 1);
l = scheme_make_null();
l = scheme_make_pair(scheme_intern_symbol(APP_NAME), l);
l = scheme_make_pair(scheme_intern_symbol("quote"), l);
a[0] = l;
a[1] = scheme_false;
2020-10-15 02:18:35 +00:00
save = scheme_current_thread->error_buf;
scheme_current_thread->error_buf = &fresh;
if (scheme_setjmp(scheme_error_buf)) {
fprintf(stderr, "[WRAPPER] encountered top-level racket error. aborting\n");
rv = -1;
} else {
scheme_dynamic_require(2, a);
}
2020-10-15 02:18:35 +00:00
scheme_current_thread->error_buf = (mz_jmp_buf*) save;
MZ_GC_UNREG();
2020-10-15 02:18:35 +00:00
return rv;
}
int main(int argc, char *argv[]) {
return scheme_main_setup(1, run_bc, argc, argv);
}