#include "inc/priv.h"#include "inc/cvalues.h"#include "inc/print.h"#include "inc/io.h"#include "inc/nan.h"#include "brieflz.h" #if !defined(ARGBEGIN)/* straight from 9front */static char *argv0 = nil;#define ARGBEGIN \ for((argv0 ? nil : (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 EARGF(x) (_argt=_args, _args="", (*_argt? _argt: argv[1]? (argc--, *++argv): (x, (char*)0)))#endif #define SL_TRY_EXTERN \ sl_exctx _ctx; \ sl_savestate(&_ctx); \ sl.exctx = &_ctx; \ int l__ca; \ if(!sl_setjmp(_ctx.buf)) \ for(int l__tr = 1; l__tr; l__tr = 0, sl.exctx = sl.exctx->prev) #define SL_CATCH_EXTERN_NO_RESTORE \ else \ for(l__ca=1; l__ca;) sl_nonnull(2) sl_rd(2, 1)static sl_vargv_list(int argc, char **argv){ int i; sl_v lst = sl_nil, temp = sl_nil; sl_gc_handle(&lst); sl_gc_handle(&temp); for(i = argc-1; i >= 0; i--){ temp = cvalue_static_cstr(argv[i]); lst = mk_cons(temp, lst); } lst = mk_cons(cvalue_static_cstr(argv0), lst); sl_free_gc_handles(2); return lst;} sl_nonnull(1)static voidsizesuffix(usize *sz, char su){ switch(tolower(su)){ case 'k': case 'K': *sz *= 1024ULL; break; case 'm': case 'M': *sz *= 1024ULL*1024ULL; break; case 'g': case 'G': *sz *= 1024ULL*1024ULL*1024ULL; sl_fallthrough; case 0: break; default: sysfatal("invalid size suffix '%c'", su); }} _Noreturn static voidusage(void){ ios_printf(ios_stderr, "%s: [-i] [-B sl.boot] [-H heapsize] ...\n", argv0); sys_exit("usage", 1);} _Noreturn voidslmain(const u8int *boot, int bootsz, int argc, char **argv){ static u8int *tmpboot = nil; usize heapsize = HEAP_SIZE0; sl_v interactive; char *e; nan_init(); ios_init_std(); mpsetminbits(sizeof(sl_fx)*8); interactive = sl_nil; ARGBEGIN{ case 'B': { ios b, bin, *s; if((s = ios_file(&bin, EARGF(usage()), IOS_READ, 0644)) == nil) sysfatal("failed to open boot image"); ios_mem(&b, 0); if((bootsz = ios_copyall(&b, s)) < 0) sysfatal("failed to read boot image"); tmpboot = MEM_ALLOC(bootsz); memcpy(tmpboot, b.buf, bootsz); boot = tmpboot; ios_close(s); ios_close(&b); break; } case 'H': heapsize = strtoull(EARGF(usage()), &e, 0); sizesuffix(&heapsize, *e); break; case 'i': interactive = sl_t; break; case 'h': usage(); default: break; }ARGEND if(sl_init(heapsize) != 0) sysfatal("init failed"); if(bootsz > 0 && boot[0] == 0){ u32int unpackedsz = boot[1]<<0 | boot[2]<<8 | boot[3]<<16| boot[4]<<24; tmpboot = MEM_ALLOC(unpackedsz); if(tmpboot == nil) sl_exit("no memory", 1); unsigned long n = blz_depack_safe(boot+5, bootsz-5, tmpboot, unpackedsz); if(n == BLZ_ERROR) sysfatal("failed to unpack boot image"); boot = tmpboot; bootsz = n; } static ios s; ios_static_buffer(&s, boot, bootsz); MEM_FREE(s.filename); s.filename = MEM_STRDUP("sl.boot"); sl_v args = argv_list(argc, argv); sl_gc_handle(&args); sl_gc_handle(&interactive); sl_v f = cvalue_from_ref(sl_iotype, &s, sizeof(ios)); if(sl_load_system_image(f) != 0) sysfatal("load failed"); int code = 0; SL_TRY_EXTERN{ MEM_FREE(tmpboot); ios_close(&s); ios_free(&s); sl_free_gc_handles(2); sl_v sym = mk_sym("__start", false); sl_v start = sym_value(sym); if(start == sl_unbound) sl_unbound_error(sym); sl_applyn(2, start, args, interactive); } SL_CATCH_EXTERN_NO_RESTORE{ sl.pr.f = ios_stderr; ios_printf(sl.pr.f, "start: error raised: "); sl_print(sl.lasterror); ios_putc(sl.pr.f, '\n'); break; } if(code != 0) sysfatal("start failed"); sys_exit(nil, code);}
#include "inc/priv.h"
#include "inc/cvalues.h"
#include "inc/print.h"
#include "inc/io.h"
#include "inc/nan.h"
#include "brieflz.h"
#if !defined(ARGBEGIN)
/* straight from 9front */
static char *argv0 = nil;
#define ARGBEGIN \
for((argv0 ? nil : (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 EARGF(x) (_argt=_args, _args="", (*_argt? _argt: argv[1]? (argc--, *++argv): (x, (char*)0)))
#endif
#define SL_TRY_EXTERN \
sl_exctx _ctx; \
sl_savestate(&_ctx); \
sl.exctx = &_ctx; \
int l__ca; \
if(!sl_setjmp(_ctx.buf)) \
for(int l__tr = 1; l__tr; l__tr = 0, sl.exctx = sl.exctx->prev)
#define SL_CATCH_EXTERN_NO_RESTORE \
else \
for(l__ca=1; l__ca;)
sl_nonnull(2) sl_rd(2, 1)
static sl_v
argv_list(int argc, char **argv)
{
int i;
sl_v lst = sl_nil, temp = sl_nil;
sl_gc_handle(&lst);
sl_gc_handle(&temp);
for(i = argc-1; i >= 0; i--){
temp = cvalue_static_cstr(argv[i]);
lst = mk_cons(temp, lst);
}
lst = mk_cons(cvalue_static_cstr(argv0), lst);
sl_free_gc_handles(2);
return lst;
}
sl_nonnull(1)
static void
sizesuffix(usize *sz, char su)
{
switch(tolower(su)){
case 'k':
case 'K':
*sz *= 1024ULL;
break;
case 'm':
case 'M':
*sz *= 1024ULL*1024ULL;
break;
case 'g':
case 'G':
*sz *= 1024ULL*1024ULL*1024ULL;
sl_fallthrough;
case 0:
break;
default:
sysfatal("invalid size suffix '%c'", su);
}
}
_Noreturn static void
usage(void)
{
ios_printf(ios_stderr, "%s: [-i] [-B sl.boot] [-H heapsize] ...\n", argv0);
sys_exit("usage", 1);
}
_Noreturn void
slmain(const u8int *boot, int bootsz, int argc, char **argv)
{
static u8int *tmpboot = nil;
usize heapsize = HEAP_SIZE0;
sl_v interactive;
char *e;
nan_init();
ios_init_std();
mpsetminbits(sizeof(sl_fx)*8);
interactive = sl_nil;
ARGBEGIN{
case 'B': {
ios b, bin, *s;
if((s = ios_file(&bin, EARGF(usage()), IOS_READ, 0644)) == nil)
sysfatal("failed to open boot image");
ios_mem(&b, 0);
if((bootsz = ios_copyall(&b, s)) < 0)
sysfatal("failed to read boot image");
tmpboot = MEM_ALLOC(bootsz);
memcpy(tmpboot, b.buf, bootsz);
boot = tmpboot;
ios_close(s);
ios_close(&b);
break;
}
case 'H':
heapsize = strtoull(EARGF(usage()), &e, 0);
sizesuffix(&heapsize, *e);
break;
case 'i':
interactive = sl_t;
break;
case 'h':
usage();
default:
break;
}ARGEND
if(sl_init(heapsize) != 0)
sysfatal("init failed");
if(bootsz > 0 && boot[0] == 0){
u32int unpackedsz =
boot[1]<<0 |
boot[2]<<8 |
boot[3]<<16|
boot[4]<<24;
tmpboot = MEM_ALLOC(unpackedsz);
if(tmpboot == nil)
sl_exit("no memory", 1);
unsigned long n = blz_depack_safe(boot+5, bootsz-5, tmpboot, unpackedsz);
if(n == BLZ_ERROR)
sysfatal("failed to unpack boot image");
boot = tmpboot;
bootsz = n;
}
static ios s;
ios_static_buffer(&s, boot, bootsz);
MEM_FREE(s.filename);
s.filename = MEM_STRDUP("sl.boot");
sl_v args = argv_list(argc, argv);
sl_gc_handle(&args);
sl_gc_handle(&interactive);
sl_v f = cvalue_from_ref(sl_iotype, &s, sizeof(ios));
if(sl_load_system_image(f) != 0)
sysfatal("load failed");
int code = 0;
SL_TRY_EXTERN{
MEM_FREE(tmpboot);
ios_close(&s);
ios_free(&s);
sl_free_gc_handles(2);
sl_v sym = mk_sym("__start", false);
sl_v start = sym_value(sym);
if(start == sl_unbound)
sl_unbound_error(sym);
sl_applyn(2, start, args, interactive);
}
SL_CATCH_EXTERN_NO_RESTORE{
sl.pr.f = ios_stderr;
ios_printf(sl.pr.f, "start: error raised: ");
sl_print(sl.lasterror);
ios_putc(sl.pr.f, '\n');
break;
}
if(code != 0)
sysfatal("start failed");
sys_exit(nil, code);
}