diff --git a/bin/mlton-script b/bin/mlton-script index 296a2867a..ea8d8768a 100644 --- a/bin/mlton-script +++ b/bin/mlton-script @@ -118,6 +118,9 @@ for arg in "$@"; do -target-cc-opt ia64-hpux "-mlp64" \ -target-cc-opt ia64 "-mtune=itanium2" \ -target-cc-opt sparc '-m32 -mcpu=v8 -Wa,-xarch=v8plusa' \ + -target-cc-opt wasi '-D_WASI_EMULATED_SIGNAL' \ + -target-cc-opt wasi '-D_WASI_EMULATED_PROCESS_CLOCKS' \ + -target-cc-opt wasi '-D_WASI_EMULATED_GETPID' \ -target-cc-opt x86 '-m32' \ -target-link-opt aix '-maix64' \ -target-link-opt alpha \ @@ -134,6 +137,9 @@ for arg in "$@"; do -target-link-opt mingw '-Wl,--enable-stdcall-fixup' \ -target-link-opt openbsd '-Wl,--no-execute-only' \ -target-link-opt solaris '-lnsl -lsocket -lrt' \ + -target-link-opt wasi '-lwasi-emulated-signal' \ + -target-link-opt wasi '-lwasi-emulated-process-clocks' \ + -target-link-opt wasi '-lwasi-emulated-getpid' \ -target-link-opt x86 '-m32' \ -profile-exclude '\$\(SML_LIB\)' fi diff --git a/runtime/Makefile b/runtime/Makefile index ddbb740ff..89767521c 100644 --- a/runtime/Makefile +++ b/runtime/Makefile @@ -20,6 +20,8 @@ endif EXE := +WASMTIME := + MDVARIANTS := OPT DBG PIVARIANTS := DPI NPI PIC PIE @@ -110,6 +112,16 @@ ifeq ($(TARGET_OS), cygwin) EXE := .exe endif +ifeq ($(TARGET_OS), wasi) +WASMTIME := wasmtime +XCPPFLAGS += -D_WASI_EMULATED_SIGNAL \ + -D_WASI_EMULATED_PROCESS_CLOCKS \ + -D_WASI_EMULATED_GETPID +XLDFLAGS += -lwasi-emulated-signal \ + -lwasi-emulated-process-clocks \ + -lwasi-emulated-getpid +endif + ifeq ($(TARGET_OS), mingw) EXE := .exe # GCC doesn't recognize the %I64 format specifier which means %ll on windows @@ -239,11 +251,11 @@ ml-types.h: gen/ml-types.h $(CP) $< $@ gen/ml-types.h: gen/gen-types$(EXE) - ./gen/gen-types$(EXE) ml-types.h > gen/ml-types.h + $(WASMTIME) ./gen/gen-types$(EXE) ml-types.h > gen/ml-types.h gen/c-types.h: gen/gen-types$(EXE) - ./gen/gen-types$(EXE) c-types.h > gen/c-types.h + $(WASMTIME) ./gen/gen-types$(EXE) c-types.h > gen/c-types.h gen/c-types.sml: gen/gen-types$(EXE) - ./gen/gen-types$(EXE) c-types.sml > gen/c-types.sml + $(WASMTIME) ./gen/gen-types$(EXE) c-types.sml > gen/c-types.sml ifneq ($(MAKECMDGOALS),clean) -include gen/gen-types.d @@ -262,7 +274,7 @@ gen/$(1): gen/gen-basis-ffi.sml gen/basis-ffi.def touch gen/$(1) else gen/$(1): gen/gen-basis-ffi$(EXE) gen/basis-ffi.def - ./gen/gen-basis-ffi$(EXE) $(1) < gen/basis-ffi.def > gen/$(1) + $(WASMTIME) ./gen/gen-basis-ffi$(EXE) $(1) < gen/basis-ffi.def > gen/$(1) $(CAT) gen/gen-basis-ffi.sml gen/basis-ffi.def gen/$(1) | $(SHA1DGST) > gen/$(1).chk endif endef @@ -307,7 +319,7 @@ gdtoa/README: gdtoa.tgz gdtoa.may_alias-unions.patch gdtoa.rename-public-fns.pat @touch $@ gdtoa/arith.h: gdtoa/arithchk$(EXE) - ./gdtoa/arithchk$(EXE) > gdtoa/arith.h + $(WASMTIME) ./gdtoa/arithchk$(EXE) > gdtoa/arith.h gdtoa/arithchk.c: gdtoa/README @touch $@ @@ -319,7 +331,7 @@ ifneq ($(MAKECMDGOALS),clean) endif gdtoa/gd_qnan.h: gdtoa/qnan$(EXE) - ./gdtoa/qnan$(EXE) > gdtoa/gd_qnan.h + $(WASMTIME) ./gdtoa/qnan$(EXE) > gdtoa/gd_qnan.h gdtoa/qnan.c: gdtoa/README @touch $@ @@ -348,7 +360,7 @@ $(eval $(call A_TEMPLATE,mlton,MLTON)) ### gen/constants ### gen/constants: gen/gen-constants$(EXE) - ./gen/gen-constants > gen/constants + $(WASMTIME) ./gen/gen-constants > gen/constants ifneq ($(MAKECMDGOALS),clean) -include gen/gen-constants.d diff --git a/runtime/cenv.h b/runtime/cenv.h index e21503517..7e40347df 100644 --- a/runtime/cenv.h +++ b/runtime/cenv.h @@ -82,6 +82,8 @@ COMPILE_TIME_ASSERT(sizeof_double__is_eight, sizeof(double) == 8); #include "platform/openbsd.h" #elif (defined (__sun__)) #include "platform/solaris.h" +#elif (defined (__wasi__)) +#include "platform/wasi.h" #else #error unknown platform os #endif @@ -117,6 +119,8 @@ COMPILE_TIME_ASSERT(sizeof_double__is_eight, sizeof(double) == 8); #include "platform/x86.h" #elif (defined (__loongarch64)) #include "platform/loongarch64.h" +#elif (defined (__wasm32)) +#include "platform/wasm32.h" #else #error unknown platform arch #endif diff --git a/runtime/gc/heap.c b/runtime/gc/heap.c index af1d9f8bb..668315d51 100644 --- a/runtime/gc/heap.c +++ b/runtime/gc/heap.c @@ -183,7 +183,9 @@ void shrinkHeap (GC_state s, GC_heap h, size_t keepSize) { } assert (isAligned (keepWithMapsSize, s->sysvals.pageSize)); assert (keepWithMapsSize <= h->withMapsSize); +#if HAS_SHRINK_HEAP GC_release (h->start + keepWithMapsSize, h->withMapsSize - keepWithMapsSize); +#endif h->size = keepSize; h->withMapsSize = keepWithMapsSize; } diff --git a/runtime/platform.h b/runtime/platform.h index 6c3a44cfd..c88ea3b85 100644 --- a/runtime/platform.h +++ b/runtime/platform.h @@ -35,6 +35,10 @@ #error HAS_REMAP not defined #endif +#ifndef HAS_SHRINK_HEAP +#error HAS_SHRINK_HEAP not defined +#endif + #ifndef HAS_SIGALTSTACK #error HAS_SIGALTSTACK not defined #else diff --git a/runtime/platform/aix.h b/runtime/platform/aix.h index 4869551f3..f7bb19037 100644 --- a/runtime/platform/aix.h +++ b/runtime/platform/aix.h @@ -34,6 +34,7 @@ #define HAS_MSG_DONTWAIT FALSE #define HAS_PTRACE FALSE #define HAS_REMAP FALSE +#define HAS_SHRINK_HEAP TRUE #define HAS_SIGALTSTACK TRUE #define NEEDS_SIGALTSTACK_EXEC FALSE #define HAS_SPAWN FALSE diff --git a/runtime/platform/cygwin.h b/runtime/platform/cygwin.h index 644fec5aa..29a0e7bae 100644 --- a/runtime/platform/cygwin.h +++ b/runtime/platform/cygwin.h @@ -35,6 +35,7 @@ #define HAS_FEROUND FALSE #define HAS_REMAP TRUE +#define HAS_SHRINK_HEAP TRUE #define HAS_SIGALTSTACK FALSE #define NEEDS_SIGALTSTACK_EXEC FALSE #define HAS_SPAWN TRUE diff --git a/runtime/platform/darwin.h b/runtime/platform/darwin.h index e5af03e32..ac2a0d936 100644 --- a/runtime/platform/darwin.h +++ b/runtime/platform/darwin.h @@ -34,6 +34,7 @@ #define HAS_FEROUND TRUE #define HAS_MSG_DONTWAIT TRUE #define HAS_REMAP FALSE +#define HAS_SHRINK_HEAP TRUE #define HAS_SIGALTSTACK TRUE #define NEEDS_SIGALTSTACK_EXEC FALSE #define HAS_SPAWN FALSE diff --git a/runtime/platform/freebsd.h b/runtime/platform/freebsd.h index 85d685df0..919127ec1 100644 --- a/runtime/platform/freebsd.h +++ b/runtime/platform/freebsd.h @@ -30,6 +30,7 @@ #define HAS_FEROUND TRUE #define HAS_MSG_DONTWAIT TRUE #define HAS_REMAP FALSE +#define HAS_SHRINK_HEAP TRUE #define HAS_SIGALTSTACK TRUE #define NEEDS_SIGALTSTACK_EXEC FALSE #define HAS_SPAWN FALSE diff --git a/runtime/platform/hpux.h b/runtime/platform/hpux.h index 62d83b649..aa8de42de 100644 --- a/runtime/platform/hpux.h +++ b/runtime/platform/hpux.h @@ -52,6 +52,7 @@ #define HAS_FEROUND TRUE #define HAS_MSG_DONTWAIT FALSE #define HAS_REMAP FALSE +#define HAS_SHRINK_HEAP TRUE #define HAS_SIGALTSTACK TRUE #define NEEDS_SIGALTSTACK_EXEC FALSE #define HAS_SPAWN FALSE diff --git a/runtime/platform/hurd.h b/runtime/platform/hurd.h index 7dbc46d5c..68fc44e88 100644 --- a/runtime/platform/hurd.h +++ b/runtime/platform/hurd.h @@ -30,6 +30,7 @@ #define HAS_FEROUND TRUE #define HAS_MSG_DONTWAIT TRUE #define HAS_REMAP TRUE +#define HAS_SHRINK_HEAP TRUE #define HAS_SIGALTSTACK TRUE #define NEEDS_SIGALTSTACK_EXEC FALSE #define HAS_SPAWN FALSE diff --git a/runtime/platform/linux.h b/runtime/platform/linux.h index 3f1ce7a60..423f9e11b 100644 --- a/runtime/platform/linux.h +++ b/runtime/platform/linux.h @@ -38,6 +38,7 @@ #endif #define HAS_MSG_DONTWAIT TRUE #define HAS_REMAP TRUE +#define HAS_SHRINK_HEAP TRUE #define HAS_SIGALTSTACK TRUE #if (defined (__hppa__)) #define NEEDS_SIGALTSTACK_EXEC TRUE diff --git a/runtime/platform/mingw.h b/runtime/platform/mingw.h index f99352eb0..7441ee5e2 100644 --- a/runtime/platform/mingw.h +++ b/runtime/platform/mingw.h @@ -33,6 +33,7 @@ #define HAS_FEROUND FALSE #define HAS_MSG_DONTWAIT FALSE #define HAS_REMAP TRUE +#define HAS_SHRINK_HEAP TRUE #define HAS_SIGALTSTACK FALSE #define NEEDS_SIGALTSTACK_EXEC FALSE #define HAS_SPAWN TRUE diff --git a/runtime/platform/netbsd.h b/runtime/platform/netbsd.h index d2aef2e84..6bea1a501 100644 --- a/runtime/platform/netbsd.h +++ b/runtime/platform/netbsd.h @@ -30,6 +30,7 @@ #define HAS_FEROUND FALSE #define HAS_MSG_DONTWAIT TRUE #define HAS_REMAP FALSE +#define HAS_SHRINK_HEAP TRUE #define HAS_SIGALTSTACK TRUE #define NEEDS_SIGALTSTACK_EXEC FALSE #define HAS_SPAWN FALSE diff --git a/runtime/platform/openbsd.h b/runtime/platform/openbsd.h index c6ca591e6..ffb816e0c 100644 --- a/runtime/platform/openbsd.h +++ b/runtime/platform/openbsd.h @@ -30,6 +30,7 @@ #define HAS_FEROUND FALSE #define HAS_MSG_DONTWAIT TRUE #define HAS_REMAP FALSE +#define HAS_SHRINK_HEAP TRUE #define HAS_SIGALTSTACK TRUE #define NEEDS_SIGALTSTACK_EXEC FALSE #define HAS_SPAWN FALSE diff --git a/runtime/platform/solaris.h b/runtime/platform/solaris.h index 456d7fc7e..b752f3454 100644 --- a/runtime/platform/solaris.h +++ b/runtime/platform/solaris.h @@ -34,6 +34,7 @@ #define HAS_FEROUND TRUE #define HAS_MSG_DONTWAIT TRUE #define HAS_REMAP FALSE +#define HAS_SHRINK_HEAP TRUE #define HAS_SIGALTSTACK TRUE #define NEEDS_SIGALTSTACK_EXEC FALSE #define HAS_SPAWN FALSE diff --git a/runtime/platform/wasi.c b/runtime/platform/wasi.c new file mode 100644 index 000000000..42dc82b44 --- /dev/null +++ b/runtime/platform/wasi.c @@ -0,0 +1,71 @@ +#include "platform.h" + +/* WASI only implements a subset of POSIX, and given how it works it doesn't + * make too much sense to try too hard to emulate missing functionality. + * + * Every function needed by the runtime library and not provided by WASI + * is declared in wasi.h, but only a tiny number are implemented here. + * + * This means that any use of missing runtime functions from SML code will + * result in linker errors at the end of compilation, rather than as a runtime + * error later. + * + * The functions in this file are the bare minimum to get the GC working, + * needed by every program compiled by MLton. + */ + +size_t GC_pageSize (void) { + return PAGESIZE; +} + +uintmax_t GC_physMem (void) { + /* WASI doesn't provide a way to query actual physical memory, so pick + * a reasonable amount (as of Feb 2024). + */ + return 1 << 30; /* 1 GiB */ +} + +void *GC_mmapAnon (__attribute__ ((unused)) void *start, size_t length) { + void *mem; + int err = posix_memalign (&mem, PAGESIZE, length); + if (err) { + return (void *) -1; + } + return memset (mem, 0, length); +} + +void *GC_mmapAnonFlags (void *start, size_t length, + __attribute__ ((unused)) int flags) { + return GC_mmapAnon (start, length); +} + +void GC_release (void *base, __attribute__ ((unused)) size_t length) { + free (base); +} + +void GC_displayMem (void) { + size_t memory_size = (size_t) sbrk(0); + size_t pages = memory_size / PAGESIZE; + printf ("memory.size: pages=%zu, pagesize=%d, total=%zu\n", + pages, PAGESIZE, memory_size); +} + +void GC_diskBack_close (__attribute__ ((unused)) void *data) { + die ("Disk-backed heap not supported on WASI"); +} + +void GC_diskBack_read (__attribute__ ((unused)) void *data, + __attribute__ ((unused)) pointer buf, + __attribute__ ((unused)) size_t size) { + die ("Disk-backed heap not supported on WASI"); +} + +void *GC_diskBack_write (__attribute__ ((unused)) pointer buf, + __attribute__ ((unused)) size_t size) { + die ("Disk-backed heap not supported on WASI"); +} + +int sigemptyset (sigset_t *set) { + *set = (sigset_t) 0; + return 0; +} diff --git a/runtime/platform/wasi.h b/runtime/platform/wasi.h new file mode 100644 index 000000000..e978246bf --- /dev/null +++ b/runtime/platform/wasi.h @@ -0,0 +1,490 @@ +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define HAS_FEROUND TRUE +#define HAS_MSG_DONTWAIT TRUE +#define HAS_REMAP FALSE +#define HAS_SHRINK_HEAP FALSE +#define HAS_SIGALTSTACK FALSE +#define NEEDS_SIGALTSTACK_EXEC FALSE +#define HAS_SPAWN FALSE +#define HAS_TIME_PROFILING FALSE + +#define MLton_Platform_OS_host "wasi" + +/* + * The definitions below are missing from WASI but are required by the runtime. + * + * In a small number of cases, these are implemented in wasi.c, but most of them + * are not. See wasi.c for a discussion. + * + * These are not guarded by ifdefs so that we can easily detect when functionality + * is added to WASI. + * + * This file is roughly based on the mingw implementation. + */ + +/* ------------------------------------------------- */ +/* Itimer */ +/* ------------------------------------------------- */ + +#define ITIMER_REAL 0 +#define ITIMER_VIRTUAL 1 +#define ITIMER_PROF 2 + +struct itimerval { + struct timeval it_interval; + struct timeval it_value; +}; + +int setitimer (int, const struct itimerval *, struct itimerval *); + +/* ------------------------------------------------- */ +/* Rlimit */ +/* ------------------------------------------------- */ + +#define RLIMIT_CPU 0 +#define RLIMIT_FSIZE 1 +#define RLIMIT_DATA 2 +#define RLIMIT_STACK 3 +#define RLIMIT_CORE 4 +#define RLIMIT_NOFILE 5 +#define RLIMIT_AS 6 +#define RLIMIT_NLIMITS 7 + +#define RLIM_INFINITY (0xffffffffUL) + +typedef unsigned long rlim_t; + +struct rlimit { + rlim_t rlim_cur; + rlim_t rlim_max; +}; + +int getrlimit (int resource, struct rlimit *); +int setrlimit (int resource, const struct rlimit *); + +/* ------------------------------------------------- */ +/* Networking */ +/* ------------------------------------------------- */ + +struct servent { + char *s_name; + char **s_aliases; + int s_port; + char *s_proto; +}; + +struct servent *getservbyname (const char *, const char *); +extern struct servent *getservbyport (int, const char *); + +struct hostent { + char *h_name; + char **h_aliases; + int h_addrtype; + int h_length; + char **h_addr_list; +}; + +struct hostent *gethostbyaddr (const void *, socklen_t, int); +struct hostent *gethostbyname (const char *); + +int socket (int, int, int); +int socketpair (int, int, int, int [2]); +int bind (int, const struct sockaddr *, socklen_t); +int connect (int, const struct sockaddr *, socklen_t); +int listen (int, int); +ssize_t recvfrom (int, void *, size_t, int, struct sockaddr *, socklen_t *); +ssize_t sendto (int, const void *, size_t, int, const struct sockaddr *, socklen_t); +int setsockopt (int, int, int, const void *, socklen_t); +int getpeername (int, struct sockaddr *, socklen_t *); +int gethostname(char *, size_t); +int getsockname (int, struct sockaddr *, socklen_t *); + +#define SIOCATMARK 0x8905 + +#define SO_DEBUG 1 +#define SO_REUSEADDR 2 +#define SO_TYPE 3 +#define SO_ERROR 4 +#define SO_DONTROUTE 5 +#define SO_BROADCAST 6 +#define SO_SNDBUF 7 +#define SO_RCVBUF 8 +#define SO_KEEPALIVE 9 +#define SO_OOBINLINE 10 +#define SO_NO_CHECK 11 +#define SO_PRIORITY 12 +#define SO_LINGER 13 +#define SO_BSDCOMPAT 14 +#define SO_REUSEPORT 15 +#define SO_PASSCRED 16 +#define SO_PEERCRED 17 +#define SO_RCVLOWAT 18 +#define SO_SNDLOWAT 19 +#define SO_ACCEPTCONN 30 +#define SO_PEERSEC 31 +#define SO_SNDBUFFORCE 32 +#define SO_RCVBUFFORCE 33 +#define SO_PROTOCOL 38 +#define SO_DOMAIN 39 +#define SO_RCVTIMEO 66 +#define SO_SNDTIMEO 67 + +#define SOCK_RAW 3 +#define SOCK_RDM 4 +#define SOCK_SEQPACKET 5 +#define SOCK_DCCP 6 +#define SOCK_PACKET 10 + +struct sockaddr_un { + sa_family_t sun_family; + char sun_path[108]; +}; + +#define MSG_OOB 0x0001 +#define MSG_DONTROUTE 0x0004 +#define MSG_CTRUNC 0x0008 +#define MSG_PROXY 0x0010 +#define MSG_DONTWAIT 0x0040 +#define MSG_EOR 0x0080 + +struct protoent { + char *p_name; + char **p_aliases; + int p_proto; +}; + +struct protoent *getprotobyname (const char *); +struct protoent *getprotobynumber (int); + +/* ------------------------------------------------- */ +/* Files */ +/* ------------------------------------------------- */ + +#define F_DUPFD 0 +#define F_GETOWN 5 +#define F_SETOWN 6 +#define F_GETLK 7 +#define F_SETLK 8 + +#define F_RDLCK 1 +#define F_WRLCK 2 +#define F_UNLCK 3 + +#define F_SETLKW 9 + +int chmod(const char *, mode_t); +int chown (const char *, uid_t, gid_t); +int fchdir (int); +int fchmod (int, mode_t); +int fchown (int, uid_t, gid_t); +long fpathconf (int, int); +int link (const char *, const char *); +int lstat (const char *, struct stat *); +int mkfifo (const char *, mode_t); +int mkstemp (char *); +long pathconf (const char *, int); +int symlink (const char *, const char *); +int truncate (const char *, off_t); +mode_t umask(mode_t); + +int dup(int); +int dup2(int, int); +int fcntl (int, int, ...); +int fsync (int); +int pipe (int [2]); + +/* ------------------------------------------------- */ +/* Processes */ +/* ------------------------------------------------- */ + +struct tms { + int tms_utime; + int tms_stime; + int tms_cutime; + int tms_cstime; +}; + +struct utsname { + char machine[20]; + char nodename[256]; + char release[20]; + char sysname[30]; + char version[20]; +}; + +char *getlogin (void); +char *ctermid (char *); +gid_t getegid (void); +uid_t geteuid (void); +gid_t getgid (void); +int getgroups (int, gid_t []); +pid_t getpgid(pid_t); +pid_t getpgrp(void); +pid_t getppid (void); +uid_t getuid (void); +int setenv (const char *, const char *, int); +int setgid (gid_t); +int setgroups (size_t, const gid_t *); +int setpgid (pid_t, pid_t); +pid_t setsid (void); +int setuid (uid_t); +clock_t times (struct tms *); +char *ttyname (int); +int uname (struct utsname *); + +#define POLLPRI 0x002 + +#define WNOHANG 1 +#define WUNTRACED 2 + +#define WIFEXITED(w) ((w) & 0) +#define WIFSIGNALED(w) ((w) & 0) +#define WIFSTOPPED(w) ((w) & 0) +#define WTERMSIG(w) ((w) & 0) +#define WEXITSTATUS(w) ((w) & 0) +#define WSTOPSIG WEXITSTATUS + +int alarm(int); +int execve(const char *, char *const [], char *const []); +int execvp(const char *, char *const []); +pid_t fork(void); +int kill(pid_t, int); +int pause(void); +pid_t waitpid (pid_t, int *, int); + +/* ------------------------------------------------- */ +/* Signals */ +/* ------------------------------------------------- */ + +#define SIG_BLOCK 0 +#define SIG_UNBLOCK 1 +#define SIG_SETMASK 2 + +struct sigaction { + int sa_flags; + sigset_t sa_mask; + void (*sa_handler)(int); +}; + +int sigaction (int, const struct sigaction *, struct sigaction *); +int sigaddset (sigset_t *, int); +int sigdelset (sigset_t *, int); +int sigemptyset (sigset_t *); +int sigfillset (sigset_t *); +int sigismember (const sigset_t *, int); +int sigpending (sigset_t *); +int sigprocmask (int, const sigset_t *, sigset_t *); +int sigsuspend (const sigset_t *); + +/* ------------------------------------------------- */ +/* Passwd */ +/* ------------------------------------------------- */ + +struct group { + gid_t gr_gid; + char **gr_mem; + char *gr_name; + char *gr_passwd; +}; + +struct passwd { + char *pw_dir; + gid_t pw_gid; + char *pw_name; + char *pw_shell; + uid_t pw_uid; +}; + +struct group *getgrgid (gid_t); +struct group *getgrnam (const char *); +struct passwd *getpwnam (const char *); +struct passwd *getpwuid (uid_t); + +/* ------------------------------------------------- */ +/* TTY */ +/* ------------------------------------------------- */ + +#define B0 0x00000 +#define B50 0x00001 +#define B75 0x00002 +#define B110 0x00003 +#define B134 0x00004 +#define B150 0x00005 +#define B200 0x00006 +#define B300 0x00007 +#define B600 0x00008 +#define B1200 0x00009 +#define B1800 0x0000a +#define B2400 0x0000b +#define B4800 0x0000c +#define B9600 0x0000d +#define B19200 0x0000e +#define B38400 0x0000f + +#define VEOL 2 +#define VEOL2 3 +#define VEOF 4 +#define VERASE 5 +#define VINTR 6 +#define VKILL 7 +#define VLNEXT 8 +#define VMIN 9 +#define VQUIT 10 +#define VREPRINT 11 +#define VSTART 12 +#define VSTOP 13 +#define VSUSP 14 +#define VSWTC 15 +#define VTIME 16 +#define VWERASE 17 +#define NCCS 18 + +#define IGNBRK 0x00001 +#define BRKINT 0x00002 +#define IGNPAR 0x00004 +#define IMAXBEL 0x00008 +#define INPCK 0x00010 +#define ISTRIP 0x00020 +#define INLCR 0x00040 +#define IGNCR 0x00080 +#define ICRNL 0x00100 +#define IXON 0x00400 +#define IXOFF 0x01000 +#define IUCLC 0x04000 +#define IXANY 0x08000 +#define PARMRK 0x10000 +#define OPOST 0x00001 + +#define CSIZE 0x00030 +#define CS5 0x00000 +#define CS6 0x00010 +#define CS7 0x00020 +#define CS8 0x00030 +#define CSTOPB 0x00040 +#define CREAD 0x00080 +#define PARENB 0x00100 +#define PARODD 0x00200 +#define HUPCL 0x00400 +#define CLOCAL 0x00800 +#define CBAUDEX 0x0100f +#define B57600 0x01001 +#define B115200 0x01002 +#define B128000 0x01003 +#define B230400 0x01004 +#define B256000 0x01005 +#define CRTSXOFF 0x04000 +#define CRTSCTS 0x08000 + +#define ISIG 0x0001 +#define ICANON 0x0002 +#define ECHO 0x0004 +#define ECHOE 0x0008 +#define ECHOK 0x0010 +#define ECHONL 0x0020 +#define NOFLSH 0x0040 +#define TOSTOP 0x0080 +#define IEXTEN 0x0100 +#define FLUSHO 0x0200 +#define ECHOKE 0x0400 +#define ECHOCTL 0x0800 + +#define TCOOFF 0 +#define TCOON 1 +#define TCIOFF 2 +#define TCION 3 + +#define TCIFLUSH 0 +#define TCOFLUSH 1 +#define TCIOFLUSH 2 +#define TCFLSH 3 + +#define TCSAFLUSH 1 +#define TCSANOW 2 +#define TCSADRAIN 3 +#define TCSADFLUSH 4 + +typedef unsigned char cc_t; +typedef unsigned int speed_t; +typedef unsigned int tcflag_t; + +struct termios { + cc_t c_cc[NCCS]; + tcflag_t c_cflag; + tcflag_t c_iflag; + tcflag_t c_lflag; + tcflag_t c_oflag; +}; + +speed_t cfgetispeed (struct termios *); +speed_t cfgetospeed (struct termios *); +int cfsetispeed (struct termios *, speed_t); +int cfsetospeed (struct termios *, speed_t); +int tcdrain (int); +int tcflow (int, int); +int tcflush (int, int); +int tcgetattr (int, struct termios *); +pid_t tcgetpgrp (int); +int tcsendbreak (int, int); +int tcsetattr (int, int, struct termios *); +int tcsetpgrp (int, pid_t); + +/* ------------------------------------------------- */ +/* Syslog */ +/* ------------------------------------------------- */ + +#define LOG_DEBUG 0 +#define LOG_INFO 1 +#define LOG_NOTICE 2 +#define LOG_WARNING 3 +#define LOG_ERR 4 +#define LOG_CRIT 5 +#define LOG_ALERT 6 +#define LOG_EMERG 7 + +#define LOG_PID 0x01 +#define LOG_CONS 0x02 +#define LOG_ODELAY 0x04 +#define LOG_NDELAY 0x08 +#define LOG_NOWAIT 0x10 +#define LOG_PERROR 0x20 + +#define LOG_AUTH 1 +#define LOG_CRON 2 +#define LOG_DAEMON 3 +#define LOG_KERN 4 +#define LOG_LOCAL0 5 +#define LOG_LOCAL1 6 +#define LOG_LOCAL2 7 +#define LOG_LOCAL3 8 +#define LOG_LOCAL4 9 +#define LOG_LOCAL5 10 +#define LOG_LOCAL6 11 +#define LOG_LOCAL7 12 +#define LOG_LPR 13 +#define LOG_MAIL 14 +#define LOG_NEWS 15 +#define LOG_SYSLOG 16 +#define LOG_USER 17 +#define LOG_UUCP 18 + +void openlog (const char *, int, int); +void closelog (void); +void syslog (int, const char *, const char *); diff --git a/runtime/platform/wasm32.h b/runtime/platform/wasm32.h new file mode 100644 index 000000000..28575ef4b --- /dev/null +++ b/runtime/platform/wasm32.h @@ -0,0 +1 @@ +#define MLton_Platform_Arch_host "wasm32"