ref: 5acf222abf7bd65e3ccfe19b30fedd361d92cd7c
dir: /src/flmain.c/
#include "flisp.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 value_t argv_list(int argc, char **argv) { int i; value_t lst = FL_nil, temp; fl_gc_handle(&lst); fl_gc_handle(&temp); for(i = argc-1; i >= 0; i--){ temp = cvalue_static_cstring(argv[i]); lst = fl_cons(temp, lst); } lst = fl_cons(cvalue_static_cstring(argv0), lst); fl_free_gc_handles(2); return lst; } static void sizesuffix(size_t *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 flmain(const uint8_t *boot, int bootsz, int argc, char **argv) { size_t heapsize = HEAP_SIZE0, stacksize = STACK_SIZE0; char *e; nan_init(); randomize(); ios_init_stdstreams(); mpsetminbits(sizeof(fixnum_t)*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(fl_init(heapsize, stacksize) != 0){ ios_puts(ios_stderr, "init failed\n"); exit(1); } value_t f = cvalue(FL(iostreamtype), (int)sizeof(ios_t)); fl_gc_handle(&f); value_t args = argv_list(argc, argv); fl_gc_handle(&args); ios_t *s = value2c(ios_t*, f); uint8_t *unpacked = nil; if(boot[0] == 0){ uint32_t 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"); fl_exit(1); } boot = unpacked; bootsz = n; } ios_static_buffer(s, boot, bootsz); int r = 1; FL_TRY_EXTERN{ if(fl_load_system_image(f) == 0){ MEM_FREE(unpacked); s = value2c(ios_t*, f); fl_free_gc_handles(2); ios_close(s); fl_applyn(1, symbol_value(symbol("__start", false)), args); r = 0; } } FL_CATCH_EXTERN_NO_RESTORE{ ios_puts(ios_stderr, "fatal error:\n"); fl_print(ios_stderr, FL(lasterror)); ios_putc(ios_stderr, '\n'); break; } fl_exit(r); }