ref: 12c9d2fc728b51aa1eb9a70d0d331eb9464912d9
dir: /src/slmain.c/
#include "sl.h"
#include "cvalues.h"
#include "print.h"
#include "iostream.h"
#include "random.h"
#include "brieflz.h"
#include "nan.h"
#if !defined(ARGBEGIN)
/* straight from 9front */
static char *argv0 = nil;
#define ARGBEGIN \
for((argv0 ? 0 : (argv0=*argv)), argv++, argc--; argv[0] && argv[0][0]=='-' && argv[0][1]; argc--, argv++){ \
const char *_args, *_argt; \
Rune _argc; \
_args = &argv[0][1]; \
if(_args[0]=='-' && _args[1]==0){ \
argc--; \
argv++; \
break; \
}\
_argc = 0; \
while(*_args && (_args += chartorune(&_argc, _args))) \
switch(_argc)
#define ARGEND USED(_argt); USED(_argc); USED(_args);}USED(argv); USED(argc);
#define ARGF() (_argt=_args, _args="", (*_argt? _argt: argv[1]? (argc--, *++argv): 0))
#define ARGC() _argc
#define EARGF(x) (_argt=_args, _args="", (*_argt? _argt: argv[1]? (argc--, *++argv): (x, (char*)0)))
#endif
static sl_v
argv_list(int argc, char **argv)
{
int i;
sl_v lst = sl_nil, temp;
sl_gc_handle(&lst);
sl_gc_handle(&temp);
for(i = argc-1; i >= 0; i--){
temp = cvalue_static_cstring(argv[i]);
lst = mk_cons(temp, lst);
}
lst = mk_cons(cvalue_static_cstring(argv0), lst);
sl_free_gc_handles(2);
return lst;
}
static void
sizesuffix(usize *sz, char su)
{
switch(tolower(su)){
case 'k':
*sz *= 1024;
break;
case 'm':
*sz *= 1024*1024;
break;
case 0:
break;
default:
ios_printf(ios_stderr, "invalid size suffix '%c'\n", su);
exit(1);
}
}
_Noreturn static void
usage(void)
{
ios_printf(ios_stderr, "%s: [-H heapsize] [-S stacksize] ...\n", argv0);
exit(0);
}
_Noreturn void
slmain(const u8int *boot, int bootsz, int argc, char **argv)
{
usize heapsize = HEAP_SIZE0, stacksize = STACK_SIZE0;
char *e;
nan_init();
randomize();
ios_init_stdstreams();
mpsetminbits(sizeof(sl_fx)*8);
ARGBEGIN{
case 'H':
heapsize = strtoull(EARGF(usage()), &e, 0);
sizesuffix(&heapsize, *e);
break;
case 'S':
stacksize = strtoull(EARGF(usage()), &e, 0);
sizesuffix(&stacksize, *e);
break;
case 'h':
usage();
default:
break;
}ARGEND
if(sl_init(heapsize, stacksize) != 0){
ios_puts(ios_stderr, "init failed\n");
exit(1);
}
sl_v f = fn_builtin_buffer(nil, 0);
sl_gc_handle(&f);
sl_v args = argv_list(argc, argv);
sl_gc_handle(&args);
sl_ios *s = value2c(sl_ios*, f);
u8int *unpacked = nil;
if(boot[0] == 0){
u32int unpackedsz =
boot[1]<<0 |
boot[2]<<8 |
boot[3]<<16|
boot[4]<<24;
unpacked = MEM_ALLOC(unpackedsz);
unsigned long n = blz_depack_safe(boot+5, bootsz-5, unpacked, unpackedsz);
if(n == BLZ_ERROR){
ios_puts(ios_stderr, "failed to unpack boot image\n");
sl_exit(1);
}
boot = unpacked;
bootsz = n;
}
ios_static_buffer(s, boot, bootsz);
int r = 1;
sl_TRY_EXTERN{
if(sl_load_system_image(f) == 0){
MEM_FREE(unpacked);
s = value2c(sl_ios*, f);
sl_free_gc_handles(2);
ios_close(s);
sl_applyn(1, symbol_value(symbol("__start", false)), args);
r = 0;
}
}
sl_CATCH_EXTERN_NO_RESTORE{
ios_puts(ios_stderr, "fatal error:\n");
sl_print(ios_stderr, sl.lasterror);
ios_putc(ios_stderr, '\n');
break;
}
sl_exit(r);
}