You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
k/0.c

163 lines
6.7 KiB

// ngn/k, (c) 2019-2022 ngn, GNU AGPLv3 - https://codeberg.org/ngn/k/raw/branch/master/LICENSE
#include"a.h"
#include<stdarg.h>
#include<stdio.h>
#include<fcntl.h>
#include<errno.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<netinet/in.h>
#include<netinet/tcp.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<sys/time.h>
#undef __USE_EXTERN_INLINES
#include<sys/stat.h>
//__builtin_ia32_ldmxcsr(__builtin_ia32_stmxcsr()|1<<6|1<<15); //daz,ftz
#ifndef shared
I main(In,Q*a)_(kinit();kargs(n,a);I r=0;I(n<2,repl())J(!bsl(a[1]),r=1;epr(0))Q(bsm(""));r)
#endif
//_start()
#if defined(libc)||defined(wasm)||defined(shared)
;
#elif defined(__OpenBSD__)||defined(__FreeBSD__)
V _start(Q*a){exit(main(*(I*)(V*)a,a+1));}
#elif defined(i386)
asm(".globl _start;_start:pop %eax;push %esp;push %eax;call main;jmp exit");
#else
asm(".globl _start;_start:pop %rdi;mov %rsp,%rsi;and $-16,%rsp;call main;mov %rax,%rdi;jmp exit");
#endif
//syscall helper macros
#if !defined(libc)&&!defined(wasm)
#include<sys/syscall.h>
#if defined(i386)
#define h(x,a...) ".globl "#x";"#x":"a"mov $"M2(SYS_##x)",%eax;int $0x80;ret;"
#define h1(x,a...) h(x,a"mov 4(%esp),%ebx;")
#define h2(x,a...) h1(x,a"mov 8(%esp),%ecx;")
#define h3(x,a...) h2(x,a"mov 12(%esp),%edx;")
#define h5(x) ".globl "#x";"#x":mov %esp,%ebx;add $4,%ebx;mov $"M2(SYS_##x)",%eax;int $0x80;ret;"
#define h6 h5
#else
#define h(x,a...) ".globl "#x";"#x":"a"movq $"M2(SYS_##x)",%rax;syscall;ret;"
#define h1 h
#define h2 h
#define h3 h
#define h4(x) h(x,"movq %rcx,%r10;")
#define h5 h4
#define h6 h4
#endif
#endif
//pipe()
#if defined(wasm)
I pipe(Iv[2])_(-1)
#elif defined(libc)
;
#elif defined(__FreeBSD__)
asm(h(pipe2));I pipe(Iv[2])_(pipe2(v,0))
#else
asm(h(pipe));
#endif
//directory iteration
#if defined(wasm)
V dir(If,void(*d)(V*,Q),V*x){}
#elif defined(libc)
#include<dirent.h>
V dir(If,void(*d)(V*,Q),V*x){DIR*a=fdopendir(f);ST dirent*e;W((e=readdir(a)),d(x,e->d_name))closedir(a);} //thanks eightsixfivezero
#else
#if defined(__FreeBSD__)
#define SYS_getdents SYS_freebsd11_getdents
TD ST{UI d_fileno;UH d_reclen;C d_type,d_namlen,d_name[255+1];}DE;
#else
TD ST{long d_ino;off_t d_off;UH d_reclen;C d_name[];}DE;
#endif
ssize_t getdents(I,C*,N);asm(h3(getdents));
V dir(If,void(*d)(V*,Q),V*x){Cb[PG];Ik;W((k=getdents(f,b,SZ b))>0,Ii=0;W(i<k,DE*e=(V*)b+i;Qs=e->d_name;d(x,s);i+=e->d_reclen))}
#endif
//getcwd()
#if defined(wasm)
C*getcwd(C*s,Nn)_((V*)0)
#elif defined(libc)
;
#elif defined(__FreeBSD__)
asm(h(__getcwd));C*__getcwd(C*,N);C*getcwd(C*s,Nn)_(__getcwd(s,n))
#else
asm(h(getcwd));
#endif
//other syscalls
#if defined(__wasi__)
#define WA(t,n,a) __attribute__((import_module("wasi_snapshot_preview1"),import_name(#n)))t n a;
WA(__attribute__((noreturn))V,proc_exit,(N))WA(UH,fd_write,(I,V*,N,N*))WA(UH,fd_read,(I,V*,N,N*))WA(UH,fd_fdstat_set_flags,(I,UH))WA(UH,clock_time_get,(I,UL,UL*))WA(UH,args_sizes_get,(N*,N*))WA(UH,args_get,(C**,C*))
I open(Qp,Iv,...)_(-1)I close(If)_(-1)I read(If,V*a,Nn)_(fd_read(f,(N[]){(N)a,n},1,&n)?-1:n)I write(If,OV*a,Nn)_(fd_write(f,(N[]){(N)a,n},1,&n)?-1:n)
off_t lseek(If,off_t o,I w)_(-1)I fstat(If,ST stat*r)_(-1)V*mmap(V*a,Nn,I pr,I fl,If,off_t o)_((V*)(__builtin_wasm_memory_grow(0,n>>16)<<16))I munmap(If,In)_(-1)
I gettimeofday(ST timeval*a,V*b)_(UL t;clock_time_get(0,-1,&t)?-1:(a->tv_sec=t/1e9,a->tv_usec=t%(L)1e9/1e3,0))
V exit(I v){proc_exit(v);}V _start(){i(3,fd_fdstat_set_flags(i,0))N i,j;args_sizes_get(&i,&j);C*v[i],b[j];args_get(v,b);exit(main(i,(Q*)v));}
I dup2(If,Iv)_(-1)I execve(Qp,char*O*a,char*O*e)_(-1)I fork()_(-1)I socket(Ii,Ij,Ik)_(-1)
I setsockopt(If,I l,I s,OV*v,socklen_t n)_(-1)I connect(If,O ST sockaddr*s,socklen_t n)_(-1)I chdir(Qp)_(-1)
I getdents(If,char*s,Nn)_(-1)I ftruncate(If,off_t o)_(-1)I wait4()_(-1)
#elif defined(wasm)
I js_in(V*,N);V js_out(OV*,N),js_log(OV*),*js_alloc(N),js_time(I*,long*),js_exit(I);
S ST{C*a,p[16];Nn;}s[8]={{.a=""},{.a=""},//s:storage,
#include"o/w/fs.h"
};S ST{C i;N o;}d[8]={{.i=1},{.i=1},{.i=1}};S O I ns=LEN(s),nd=LEN(d);//d:fd table
#define FI P((UI)f>=nd||!d[f].i,EBADF)Ii=d[f].i;//validate fd "f" and get inode "i"
I open(Qp,Iv,...)_(Im=Sn(p);P(m>=SZ s[0].p,ENAMETOOLONG)Ii=0;W(i<ns&&SQ(s[i].p,p),i++)
I(i>=ns,P(O_CREAT&~v,ENOENT)i=0;W(i<ns&&s[i].a,i++)P(i>=ns,ENOSPC)s[i].a="";s[i].n=0;Mc(s[i].p,p,m))
If=0;W(f<nd&&d[f].i,f++)P(f>=nd,EMFILE)d[f].i=i;d[f].o=0;f)
I close(If)_(FI d[f].i=0;0)
I read(If,V*a,Nn)_(FI P(i==1,js_in(a,n))I o=d[f].o;n=max(0,min(n,s[i].n-o));Mc(a,s[i].a+o,n);d[f].o+=n;n)
I write(If,OV*a,Nn)_(FI;P(i==1,js_out(a,n);n)
Im=d[f].o+n;I(m>s[i].n,C*b=js_alloc(m);Mc(b,s[i].a,n);s[i].a=b;s[i].n=m)Mc(s[i].a+d[f].o,a,n);n)
off_t lseek(If,off_t o,I w)_(FI;o=w==SEEK_CUR?o+d[f].o:w==SEEK_END?o+s[i].n:w==SEEK_SET?o:-1;P(o<0,EINVAL)d[f].o=o)
I fstat(If,ST stat*r)_(FI;In=s[i].n;
*r=(TY(*r)){.st_ino=i,.st_mode=S_IFCHR,.st_nlink=1,.st_size=n,.st_blksize=512,.st_blocks=n+511>>9};0)
V*mmap(V*a,Nn,I pr,I fl,If,off_t o)_(I(!a,a=js_alloc(n))P(f<0,a)P(f>=nd||!d[f].i,(V*)-1)Ii=d[f].i;Mc(a,s[i].a+o,n);a)
I munmap(If,In)_(0)
I gettimeofday(ST timeval*a,V*b)_(js_time((V*)&a->tv_sec,(V*)&a->tv_usec);0)
V exit(Iv){js_exit(v);}
I dup2(If,Iv)_(-1)I execve(Qp,C*O*a,C*O*e)_(-1)I fork()_(-1)I socket(Ii,Ij,Ik)_(-1)
I setsockopt(If,I l,I s,OV*v,socklen_t n)_(-1)I connect(If,O ST sockaddr*s,socklen_t n)_(-1)I chdir(Qp)_(-1)
I ftruncate(If,off_t o)_(-1)
I wait4(I i,I*l,I o,ST rusage*u)_(-1)
#elif defined(libc)
;
#else
asm(h3(read)h3(write)h3(open)h1(close)h2(fstat)h3(lseek)h2(munmap)h2(dup2)h3(socket)h5(setsockopt)h3(connect)
h(fork)h4(wait4)h3(execve)h1(exit)h2(gettimeofday)h6(mmap)h1(chdir)h2(ftruncate));
#endif
//mem and str functions
#if !defined(libc)
V*memcpy (V*x,OV*y,Nn)_(C*p=x ;Qq=y ;i(n,*p++=*q++)x)
V*memrcpy(V*x,OV*y,Nn)_(C*p=x+n;Qq=y+n;i(n,*--p=*--q)x)
V*memmove(V*x,OV*y,Nn)_((y<x&&x<y+n?memrcpy:memcpy)(x,y,n))
V*memset(V*x,Iv,Nn)_(C*p=x;i(n,*p++=v);x)
V*memchr(OV*x,Iv,Nn)_(Qs=x;i(n,P(s[i]==v,(V*)(s+i)))(V*)0)
V*memmem(OV*x,Nm,OV*y,Nn)_(Qp=x,q=y;i((L)m-(L)n+1,P(!memcmp(p+i,q,n),(V*)(p+i)))(V*)0)
I memcmp(OV*x,OV*y,Nn)_(Qs=x,t=y;i(n,Iv=*s++-*t++;P(v,v))0)
N strlen(Qs)_(Qp=s;W(1,UL v=~*(UL*)(V*)p;v&=v>>1;v&=v>>2;v&=v>>4;v&=0x0101010101010101ll;B(v)p+=8)W(*p,p++)p-s)
C*strchr(O C*s,Iv)_(W(1,P(*s==v,(V*)s)P(!*s++,(V*)0))(V*)0)
C*strstr(O C*p,O C*q)_(MM(p,Sn(p),q,Sn(q)))
I strcmp(Qp,Qq)_(W(*p&&*p==*q,p++;q++)*p-*q)
#endif
#if !defined(libc)||!defined(_GNU_SOURCE)
C*strchrnul(Qs,Iv)_(W(1,P(*s==v,(V*)s)P(!*s,(V*)s)s++)(V*)s)
#endif
//mathematical functions
#if (!defined(wasm)||defined(__wasi__))&&!defined(libc)
F sin(Fv)_(NF)F cos(Fv)_(NF)F log(Fv)_(NF)F exp(Fv)_(NF)
#endif
//`js@
#if !defined(wasm)||defined(__wasi__)
I js_eval(C*s,Im,C*r,In)_(0)
#endif