Namespace wasm

namespace wasm

SYSCALL NUMBERING

Have a look in the sysroot at include/bits/syscall.h to determine the system call numbering.

Enums

enum WAMRExceptionTypes

Values:

enumerator NoException
enumerator DefaultException
enumerator FunctionMigratedException
enumerator QueueTimeoutException
enum HostInterfaceTest

Values:

enumerator NoTest
enumerator ExceptionPropagationTest
enum ThreadRequestType

Values:

enumerator UNSET
enumerator PTHREAD
enumerator OPENMP
enum libffi_type_value

Values:

enumerator VOID
enumerator INT
enumerator FLOAT
enumerator DOUBLE
enumerator LONGDOUBLE
enumerator UINT8
enumerator SINT8
enumerator UINT16
enumerator SINT16
enumerator UINT32
enumerator SINT32
enumerator UINT64
enumerator SINT64
enumerator STRUCT
enumerator POINTER
enumerator COMPLEX
enum sched_type

Values:

enumerator sch_lower

lower bound for unordered values

enumerator sch_static_chunked
enumerator sch_static

static unspecialized

enum SocketCalls

Values:

enumerator sc_socket
enumerator sc_bind
enumerator sc_connect
enumerator sc_listen
enumerator sc_accept
enumerator sc_getsockname
enumerator sc_getpeername
enumerator sc_socketpair
enumerator sc_send
enumerator sc_recv
enumerator sc_sendto
enumerator sc_recvfrom
enumerator sc_shutdown
enumerator sc_setsockopt
enumerator sc_getsockopt
enumerator sc_sendmsg
enumerator sc_recvmsg
enumerator sc_accept4
enumerator sc_recvmmsg
enumerator sc_sendmmsg

Functions

std::shared_ptr<wasm::EnclaveWasmModule> getExecutingEnclaveWasmModule(wasm_exec_env_t execEnv)
void initialiseWAMRNatives()
uint32_t getFaasmDynlinkApi(NativeSymbol **nativeSymbols)
uint32_t getFaasmEnvApi(NativeSymbol **nativeSymbols)
uint32_t getFaasmFilesystemApi(NativeSymbol **nativeSymbols)
uint32_t getFaasmFunctionsApi(NativeSymbol **nativeSymbols)
uint32_t getFaasmMemoryApi(NativeSymbol **nativeSymbols)
uint32_t getFaasmMpiApi(NativeSymbol **nativeSymbols)
uint32_t getFaasmProcessApi(NativeSymbol **nativeSymbols)
uint32_t getFaasmPthreadApi(NativeSymbol **nativeSymbols)
uint32_t getFaasmSignalApi(NativeSymbol **nativeSymbols)
uint32_t getFaasmStateApi(NativeSymbol **nativeSymbols)
uint32_t getFaasmStubs(NativeSymbol **nativeSymbols)
uint32_t getFaasmWasiEnvApi(NativeSymbol **nativeSymbols)
uint32_t getFaasmWasiFilesystemApi(NativeSymbol **nativeSymbols)
uint32_t getFaasmWasiTimingApi(NativeSymbol **nativeSymbols)
std::vector<uint8_t> wamrCodegen(std::vector<uint8_t> &wasmBytesIn, bool isSgx)
WAMRWasmModule *getExecutingWAMRModule()
int awaitChainedCall(unsigned int messageId)
int awaitChainedCallOutput(unsigned int messageId, char *buffer, int bufferLen)
int makeChainedCall(const std::string &functionName, int wasmFuncPtr, const char *pyFunc, const std::vector<uint8_t> &inputData)
void doHostInterfaceTest(int testNum)
void doMigrationPoint(int32_t entrypointFuncWasmOffset, const std::string &entrypointFuncArg)
WasmExecutionContext *getCurrentWasmExecutionContext()
WasmModule *getExecutingModule()
bool isWasmPageAligned(int32_t offset)
size_t getNumberOfWasmPagesForBytes(size_t nBytes)
uint32_t roundUpToWasmPageAligned(uint32_t nBytes)
size_t getPagesForGuardRegion()
IRModuleCache &getIRModuleCache()
int32_t getModuleStackPointer(WAVM::Runtime::Instance *module, WAVM::Runtime::Context *context)
std::vector<uint8_t> wavmCodegen(std::vector<uint8_t> &wasmBytes)
template<class T>
T unalignedWavmRead(WAVM::Runtime::Memory *memory, WAVM::Uptr offset)
template<class T>
void unalignedWavmWrite(const T &value, WAVM::Runtime::Memory *memory, WAVM::Uptr offset)
WAVMModuleCache &getWAVMModuleCache()
WAVMWasmModule *getExecutingWAVMModule()
static int32_t dlopen_wrapper(wasm_exec_env_t exec_env, char *filename, int32_t flags)
static int32_t dlsym_wrapper(wasm_exec_env_t exec_env, void *handle, char *symbol)
static int32_t dlclose_wrapper(wasm_exec_env_t exec_env, void *handle)
static int32_t getrlimit_wrapper(wasm_exec_env_t exec_env, int32_t a, int32_t b)
uint32_t wasi_args_get(wasm_exec_env_t exec_env, uint32_t *argvOffsetsWasm, char *argvBuffWasm)
uint32_t wasi_args_sizes_get(wasm_exec_env_t exec_env, uint32_t *argcWasm, uint32_t *argvBuffSizeWasm)
uint32_t wasi_environ_get(wasm_exec_env_t exec_env, uint32_t *envOffsetsWasm, char *envBuffWasm)
uint32_t wasi_environ_sizes_get(wasm_exec_env_t exec_env, int32_t *envCountWasm, int32_t *envBufferSizeWasm)
void wasi_proc_exit(wasm_exec_env_t execEnv, int32_t retCode)
static uint32_t wasi_random_get(wasm_exec_env_t exec_env, void *buf, uint32_t bufLen)
static std::shared_ptr<faabric::state::StateKeyValue> getStateKV(int32_t *keyPtr, size_t size = 0)
static void __faasm_append_state_wrapper(wasm_exec_env_t execEnv, int32_t *keyPtr, uint8_t *dataPtr, int32_t dataLen)
static int32_t __faasm_await_call_wrapper(wasm_exec_env_t exec_env, int32_t callId)

Await a chained function’s completion

static int32_t __faasm_chain_name_wrapper(wasm_exec_env_t execEnv, const char *name, const uint8_t *input, uint32_t inputSize)

Chain a function by name

static int32_t __faasm_chain_ptr_wrapper(wasm_exec_env_t exec_env, int32_t wasmFuncPtr, char *inBuff, int32_t inLen)

Chain a function by function pointer

static void __faasm_host_interface_test_wrapper(wasm_exec_env_t execEnv, int32_t testNum)
static void __faasm_migrate_point_wrapper(wasm_exec_env_t execEnv, int32_t wasmFuncPtr, int32_t funcArg)
static void __faasm_pull_state_wrapper(wasm_exec_env_t execEnv, int32_t *keyPtr, int32_t stateLen)
static void __faasm_push_state_wrapper(wasm_exec_env_t execEnv, int32_t *keyPtr)
static void __faasm_read_appended_state_wrapper(wasm_exec_env_t execEnv, int32_t *keyPtr, uint8_t *bufferPtr, int32_t bufferLen, int32_t numElems)
static int32_t __faasm_read_input_wrapper(wasm_exec_env_t exec_env, char *inBuff, int32_t inLen)

Read the function input

static void __faasm_write_output_wrapper(wasm_exec_env_t exec_env, char *outBuff, int32_t outLen)

Set the function output

uint32_t doWasiDup(uint32_t fd)
static uint32_t __wasi_fd_dup_wrapper(wasm_exec_env_t exec_env, uint32_t fd, uint32_t *resFd)
static uint32_t dup_wrapper(wasm_exec_env_t exec_env, uint32_t fd)
static uint32_t getpwnam_wrapper(wasm_exec_env_t exec_env, uint32_t a)
static int32_t sendfile_wrapper(wasm_exec_env_t exec_env, int32_t out_fd, int32_t in_fd, int32_t offset, int32_t count)
static int32_t tempnam_wrapper(wasm_exec_env_t exec_env, int32_t a, int32_t b)
static uint32_t wasi_fd_allocate(wasm_exec_env_t exec_env, __wasi_fd_t fd, __wasi_filesize_t offset, __wasi_filesize_t len)
static int32_t wasi_fd_close(wasm_exec_env_t exec_env, int32_t fd)
static int32_t wasi_fd_fdstat_get(wasm_exec_env_t exec_env, int32_t fd, __wasi_fdstat_t *statWasm)
static int32_t wasi_fd_fdstat_set_flags(wasm_exec_env_t exec_env, int32_t a, int32_t b)
static int32_t wasi_fd_fdstat_set_rights(wasm_exec_env_t exec_env, int32_t a, int64_t b, int64_t c)
static int32_t doFileStat(uint32_t fd, const std::string &relativePath, __wasi_filestat_t *statWasm)
static int32_t wasi_fd_filestat_get(wasm_exec_env_t exec_env, int32_t fd, __wasi_filestat_t *statWasm)
static int32_t wasi_fd_filestat_set_size(wasm_exec_env_t execEnv, int32_t a, int64_t b)
static uint32_t wasi_fd_pread(wasm_exec_env_t exec_env, __wasi_fd_t fd, iovec_app_t *iovecWasm, uint32_t iovecLen, __wasi_filesize_t offset, uint32_t *nReadWasm)
static int32_t wasi_fd_prestat_dir_name(wasm_exec_env_t exec_env, int32_t fd, char *path, int32_t *pathLen)
static int32_t wasi_fd_prestat_get(wasm_exec_env_t exec_env, int32_t fd, wasi_prestat_app_t *prestatWasm)
static uint32_t wasi_fd_pwrite(wasm_exec_env_t exec_env, __wasi_fd_t fd, const iovec_app_t *iovecWasm, uint32_t iovecLen, __wasi_filesize_t offset, uint32_t *nWrittenWasm)
static int32_t wasi_fd_read(wasm_exec_env_t exec_env, int32_t fd, iovec_app_t *ioVecBuffWasm, int32_t ioVecCountWasm, int32_t *bytesRead)
static int32_t wasi_fd_readdir(wasm_exec_env_t exec_env, int32_t a, int32_t *b, char *c, int64_t d, int32_t e)
static int32_t wasi_fd_seek(wasm_exec_env_t exec_env, int32_t fd, int64_t offset, int32_t whence, __wasi_filesize_t *newOffset)
static uint32_t wasi_fd_sync(wasm_exec_env_t exec_env, __wasi_fd_t fd)
static uint32_t wasi_fd_tell(wasm_exec_env_t exec_env, uint32_t fd, uint32_t *resOffset)
static int32_t wasi_fd_write(wasm_exec_env_t exec_env, int32_t fd, iovec_app_t *ioVecBuffWasm, int32_t ioVecCountWasm, int32_t *bytesWritten)
static int32_t wasi_path_create_directory(wasm_exec_env_t exec_env, int32_t a, int32_t *b, char *c)
static int32_t wasi_path_filestat_get(wasm_exec_env_t exec_env, int32_t fd, int32_t lookupFlags, char *path, int32_t pathLen, __wasi_filestat_t *statWasm)
static uint32_t wasi_path_filestat_set_times(wasm_exec_env_t exec_env, __wasi_fd_t fd, __wasi_lookupflags_t flags, const char *path, uint32_t pathLen, __wasi_timestamp_t stAtim, __wasi_timestamp_t stMtim, __wasi_fstflags_t fstflags)
static int32_t wasi_path_link(wasm_exec_env_t exec_env, int32_t a, int32_t b, int32_t *c, char *d, int32_t e, int32_t *f, char *g)
static int32_t wasi_path_open(wasm_exec_env_t exec_env, int32_t fdNative, int32_t lookupFlags, char *path, int32_t pathLen, int32_t openFlags, int64_t rightsBase, int64_t rightsInheriting, int32_t fdFlags, int32_t *fdWasm)
static int32_t wasi_path_readlink(wasm_exec_env_t exec_env, uint32_t fd, char *path, uint32_t pathLen, char *buf, uint32_t bufLen, uint32_t *resBytesUsed)
static int32_t wasi_path_remove_directory(wasm_exec_env_t exec_env, int32_t a, int32_t *b, char *c)
static int32_t wasi_path_rename(wasm_exec_env_t exec_env, uint32_t oldFd, char *oldPath, uint32_t oldPathLen, uint32_t newFd, char *newPath, uint32_t newPathLen)
static int32_t wasi_path_symlink(wasm_exec_env_t exec_env, const char *oldPath, uint32_t oldPathLen, uint32_t fd, const char *newPath, uint32_t newPathLen)
static int32_t __sbrk_wrapper(wasm_exec_env_t exec_env, int32_t increment)
static int32_t mmap_wrapper(wasm_exec_env_t exec_env, int32_t addr, int32_t length, int32_t prot, int32_t flags, int32_t fd, int64_t offset)
static int32_t munmap_wrapper(wasm_exec_env_t exec_env, int32_t addr, int32_t length)
static MpiWorld &getExecutingWorld()
static int terminateMpi()
static int32_t MPI_Abort_wrapper(wasm_exec_env_t execEnv, int32_t a, int32_t b)
static int32_t MPI_Allgather_wrapper(wasm_exec_env_t execEnv, int32_t *sendBuf, int32_t sendCount, int32_t *sendType, int32_t *recvBuf, int32_t recvCount, int32_t *recvType, int32_t *comm)
static int32_t MPI_Allgatherv_wrapper(wasm_exec_env_t execEnv, int32_t *sendBuf, int32_t sendCount, int32_t *sendType, int32_t *recvBuf, int32_t recvCount, int32_t dspls, int32_t *recvType, int32_t *comm)
static int32_t MPI_Allreduce_wrapper(wasm_exec_env_t execEnv, int32_t *sendBuf, int32_t *recvBuf, int32_t count, int32_t *datatype, int32_t *op, int32_t *comm)
static int32_t MPI_Alltoall_wrapper(wasm_exec_env_t execEnv, int32_t *sendBuf, int32_t sendCount, int32_t *sendType, int32_t *recvBuf, int32_t recvCount, int32_t *recvType, int32_t *comm)
static int32_t MPI_Alltoallv_wrapper(wasm_exec_env_t execEnv, int32_t *sendBuf, int32_t sendCount, int32_t sdispls, int32_t *sendType, int32_t *recvBuf, int32_t recvCount, int32_t rdispls, int32_t *recvType, int32_t *comm)
static int32_t MPI_Barrier_wrapper(wasm_exec_env_t execEnv, int32_t *comm)
static int32_t MPI_Bcast_wrapper(wasm_exec_env_t execEnv, int32_t *buffer, int32_t count, int32_t *datatype, int32_t root, int32_t *comm)
static int32_t MPI_Cart_create_wrapper(wasm_exec_env_t execEnv, int32_t *oldCommPtrPtr, int32_t ndims, int32_t dims, int32_t periods, int32_t reorder, int32_t *newCommPtrPtr)
static int32_t MPI_Cart_get_wrapper(wasm_exec_env_t execEnv, int32_t *comm, int32_t maxdims, int32_t *dims, int32_t *periods, int32_t *coords)
static int32_t MPI_Cart_rank_wrapper(wasm_exec_env_t execEnv, int32_t *comm, int32_t *coords, int32_t *rank)
static int32_t MPI_Cart_shift_wrapper(wasm_exec_env_t execEnv, int32_t *comm, int32_t direction, int32_t disp, int32_t *sourceRank, int32_t *destRank)
static int32_t MPI_Comm_dup_wrapper(wasm_exec_env_t execEnv, int32_t *comm, int32_t *newComm)
static int32_t MPI_Comm_free_wrapper(wasm_exec_env_t execEnv, int32_t *comm)
static int32_t MPI_Comm_rank_wrapper(wasm_exec_env_t execEnv, int32_t *comm, int32_t *resPtr)
static int32_t MPI_Comm_size_wrapper(wasm_exec_env_t execEnv, int32_t *comm, int32_t *resPtr)
static int32_t MPI_Comm_split_wrapper(wasm_exec_env_t execEnv, int32_t *comm, int32_t color, int32_t key, int32_t *newComm)
static int32_t MPI_Finalize_wrapper(wasm_exec_env_t execEnv)
static int32_t MPI_Gather_wrapper(wasm_exec_env_t execEnv, int32_t *sendBuf, int32_t sendCount, int32_t *sendType, int32_t *recvBuf, int32_t recvCount, int32_t *recvType, int32_t root, int32_t *comm)
static int32_t MPI_Get_count_wrapper(wasm_exec_env_t execEnv, int32_t *statusPtr, int32_t *datatype, int32_t *countPtr)
static int32_t MPI_Get_processor_name_wrapper(wasm_exec_env_t execEnv, int32_t *buf, int32_t bufLen)
static int32_t MPI_Get_version_wrapper(wasm_exec_env_t execEnv, int32_t *version, int32_t *subVersion)
static int32_t MPI_Init_wrapper(wasm_exec_env_t execEnv, int32_t a, int32_t b)
static int32_t MPI_Irecv_wrapper(wasm_exec_env_t execEnv, int32_t *buffer, int32_t count, int32_t *datatype, int32_t sourceRank, int32_t tag, int32_t *comm, int32_t *requestPtrPtr)
static int32_t MPI_Isend_wrapper(wasm_exec_env_t execEnv, int32_t *buffer, int32_t count, int32_t *datatype, int32_t destRank, int32_t tag, int32_t *comm, int32_t *requestPtrPtr)
static int32_t MPI_Op_create_wrapper(wasm_exec_env_t execEnv, int32_t *userFn, int32_t commute, int32_t op)
static int32_t MPI_Op_free_wrapper(wasm_exec_env_t execEnv, int32_t *op)
static int32_t MPI_Probe_wrapper(wasm_exec_env_t execEnv, int32_t source, int32_t tag, int32_t *comm, int32_t *statusPtr)
static int32_t MPI_Recv_wrapper(wasm_exec_env_t execEnv, int32_t *buffer, int32_t count, int32_t *datatype, int32_t sourceRank, int32_t tag, int32_t *comm, int32_t *statusPtr)
static int32_t MPI_Reduce_wrapper(wasm_exec_env_t execEnv, int32_t *sendBuf, int32_t *recvBuf, int32_t count, int32_t *datatype, int32_t *op, int32_t root, int32_t *comm)
static int32_t MPI_Reduce_scatter_wrapper(wasm_exec_env_t execEnv, int32_t *sendBuf, int32_t *recvBuf, int32_t recvCount, int32_t *datatype, int32_t *op, int32_t *comm)
static int32_t MPI_Request_free_wrapper(wasm_exec_env_t execEnv, int32_t *requestPtr)
static int32_t MPI_Rsend_wrapper(wasm_exec_env_t execEnv, int32_t *buffer, int32_t count, int32_t *datatype, int32_t destRank, int32_t tag, int32_t *comm)
static int32_t MPI_Scan_wrapper(wasm_exec_env_t execEnv, int32_t *sendBuf, int32_t *recvBuf, int32_t count, int32_t *datatype, int32_t *op, int32_t *comm)
static int32_t MPI_Scatter_wrapper(wasm_exec_env_t execEnv, int32_t *sendBuf, int32_t sendCount, int32_t *sendType, int32_t *recvBuf, int32_t recvCount, int32_t *recvType, int32_t root, int32_t *comm)
static int32_t MPI_Send_wrapper(wasm_exec_env_t execEnv, int32_t *buffer, int32_t count, int32_t *datatype, int32_t destRank, int32_t tag, int32_t *comm)
static int32_t MPI_Sendrecv_wrapper(wasm_exec_env_t execEnv, int32_t *sendBuf, int32_t sendCount, int32_t *sendType, int32_t destination, int32_t sendTag, int32_t *recvBuf, int32_t recvCount, int32_t *recvType, int32_t source, int32_t recvTag, int32_t *comm, int32_t *statusPtr)
static int32_t MPI_Type_commit_wrapper(wasm_exec_env_t execEnv, int32_t *datatypePtrPtr)
static int32_t MPI_Type_contiguous_wrapper(wasm_exec_env_t execEnv, int32_t count, int32_t *oldDataTypePtr, int32_t *newDataTypePtr)
static int32_t MPI_Type_free_wrapper(wasm_exec_env_t execEnv, int32_t *datatype)
static int32_t MPI_Type_size_wrapper(wasm_exec_env_t execEnv, int32_t *typePtr, int32_t *res)
static int32_t MPI_Wait_wrapper(wasm_exec_env_t execEnv, int32_t *requestPtrPtr, int32_t status)
static int32_t MPI_Waitall_wrapper(wasm_exec_env_t execEnv, int32_t count, int32_t *requestArray, int32_t *statusArray)
static int32_t MPI_Waitany_wrapper(wasm_exec_env_t execEnv, int32_t count, int32_t *requestArray, int32_t idx, int32_t *status)
static double MPI_Wtime_wrapper()
void doSymbolRegistration(uint32_t (*f)(NativeSymbol **ns))
void doWasiSymbolRegistration(uint32_t (*f)(NativeSymbol **ns))
static uint32_t getpid_wrapper(wasm_exec_env_t exec_env, uint32_t a)
static uint32_t pclose_wrapper(wasm_exec_env_t exec_env, uint32_t a)
static uint32_t popen_wrapper(wasm_exec_env_t exec_env, uint32_t a, uint32_t b)
static uint32_t raise_wrapper(wasm_exec_env_t exec_env, uint32_t a)
static uint32_t system_wrapper(wasm_exec_env_t exec_env, uint32_t a)
static int32_t pthread_create_wrapper(wasm_exec_env_t exec_env, int32_t a, int32_t b, int32_t c, int32_t d)
static int32_t pthread_join_wrapper(wasm_exec_env_t exec_env, int32_t a, int32_t b)
static int32_t pthread_once_wrapper(wasm_exec_env_t exec_env, int32_t a, int32_t b)
static int32_t pthread_mutex_init_wrapper(wasm_exec_env_t exec_env, int32_t a, int32_t b)
static int32_t pthread_mutex_lock_wrapper(wasm_exec_env_t exec_env, int32_t a)
static int32_t pthread_mutex_unlock_wrapper(wasm_exec_env_t exec_env, int32_t a)
static int32_t pthread_mutex_destroy_wrapper(wasm_exec_env_t exec_env, int32_t a)
static int32_t pthread_cond_init_wrapper(wasm_exec_env_t exec_env, int32_t a, int32_t b)
static int32_t pthread_cond_signal_wrapper(wasm_exec_env_t exec_env, int32_t a)
static int32_t pthread_cond_wait_wrapper(wasm_exec_env_t exec_env, int32_t a, int32_t b)
static int32_t pthread_cond_broadcast_wrapper(wasm_exec_env_t exec_env, int32_t a)
static int32_t pthread_cond_destroy_wrapper(wasm_exec_env_t exec_env, int32_t a)
static int32_t pthread_mutexattr_init_wrapper(wasm_exec_env_t exec_env, int32_t a)
static int32_t pthread_mutexattr_destroy_wrapper(wasm_exec_env_t exec_env, int32_t a)
static int32_t pthread_equal_wrapper(wasm_exec_env_t exec_env, int32_t a, int32_t b)
static uint32_t signal_wrapper(wasm_exec_env_t exec_env, uint32_t a, uint32_t b)
static int32_t __faasm_read_state_wrapper(wasm_exec_env_t exec_env, char *key, char *buffer, int32_t bufferLen)

Read state for the given key into the buffer provided.

Returns size of the state if buffer length is zero.

static int32_t __faasm_read_state_ptr_wrapper(wasm_exec_env_t exec_env, char *key, int32_t bufferLen)

Create a new memory region, read the state for the given key into it, then return a pointer to the new memory.

static void __faasm_write_state_wrapper(wasm_exec_env_t exec_env, char *key, char *buffer, int32_t bufferLen)

Writes the given data buffer to the state referenced by the given key.

static void __faasm_push_state_wrapper(wasm_exec_env_t exec_env, char *key)

Pushes the state for the given key

static int32_t syscall_wrapper(wasm_exec_env_t exec_env, int32_t syscallNo, int32_t syscallArgs)
static int32_t __cxa_allocate_exception_wrapper(wasm_exec_env_t exec_env, int32_t a)
static void __cxa_throw_wrapper(wasm_exec_env_t exec_env, int32_t a, int32_t b, int32_t c)
static int32_t shm_open_wrapper(wasm_exec_env_t exec_env, char *a, int32_t b, int32_t c)
uint32_t wasi_clock_time_get(wasm_exec_env_t exec_env, int32_t clockId, int64_t precision, int32_t *result)
uint32_t wasi_poll_oneoff(wasm_exec_env_t exec_env, int32_t *subscriptionsPtr, int64_t *eventsPtr, int32_t nSubs, int32_t *resNEvents)
void chainLink()
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__faasm_await_call", I32, __faasm_await_call, U32 messageId)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__faasm_await_call_output", I32, __faasm_await_call_output, U32 messageId, I32 bufferPtr, I32 bufferLen)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__faasm_chain_name", U32, __faasm_chain_name, I32 namePtr, I32 inputDataPtr, I32 inputDataLen)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__faasm_chain_ptr", U32, __faasm_chain_ptr, I32 wasmFuncPtr, I32 inputDataPtr, I32 inputDataLen)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__faasm_chain_py", U32, __faasm_chain_py, I32 namePtr, I32 inputDataPtr, I32 inputDataLen)
void dynlinkLink()
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "dlopen", I32, dlopen, I32 fileNamePtr, I32 flags)

WebAssembly official docs on dynamic linking: https://webassembly.org/docs/dynamic-linking/

Tool conventions: https://github.com/WebAssembly/tool-conventions/blob/main/DynamicLinking.md

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "dlsym", I32, dlsym, I32 handle, I32 symbolPtr)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "dlerror", I32, dlerror)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "dlclose", I32, dlclose, I32 handle)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "ffi_call", void, ffi_call, I32 cifPtr, I32 fnPtr, I32 retPtr, I32 argsPtrPtr)

The implementation of ffi_call is language-specific. The signature is:

void ffi_call(ffi_cif *cif, void (*fn)(void), void *ret, void **args);

  • cif = function definition

  • fn = function pointer

  • ret = return value address

  • args = arguments

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "ffi_prep_closure_loc", I32, ffi_prep_closure_loc, I32 a, I32 b, I32 c, I32 d, I32 e)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "args_sizes_get", I32, wasi_args_sizes_get, I32 argcPtr, I32 argvBufSize)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "args_get", I32, wasi_args_get, I32 argvPtr, I32 argvBufPtr)
I32 s__gettid()
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "geteuid", I32, geteuid)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "getegid", I32, getegid)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "getgrgid", I32, getgrgid, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "getgrnam", I32, getgrnam, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "setgrent", void, setgrent)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "getgrent", I32, getgrent)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "endgrent", void, endgrent)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "getpwuid", I32, getpwuid, I32 uid)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "getuid", I32, getuid)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "getgid", I32, getgid)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "getppid", I32, getppid)
I32 s__exit(I32 a, I32 b)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "proc_exit", void, wasi_proc_exit, I32 retCode)
I32 s__sched_getaffinity(I32 pid, I32 cpuSetSize, I32 maskPtr)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "confstr", I32, confstr, I32 a, I32 b, I32 c)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "abort", void, abort)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "exit", void, exit, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "_Exit", void, _Exit, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "sysconf", I32, _sysconf, I32 a)

Allowing straight-through access to sysconf my not be wise. Should revisit this.

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "uname", I32, uname, I32 bufPtr)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "environ_sizes_get", I32, wasi_environ_sizes_get, I32 environCountPtr, I32 environBuffSizePtr)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "environ_get", I32, wasi_environ_get, I32 environPtrs, I32 environBuf)
I32 s__getrandom(I32 bufPtr, I32 bufLen, I32 flags)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "random_get", I32, wasi_random_get, I32 bufPtr, I32 bufLen)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__h_errno_location", I32, __h_errno_location)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "ttyname", I32, ttyname, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "getpwnam", I32, getpwnam, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "getresuid", I32, getresuid, I32 a, I32 b, I32 c)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "getresgid", I32, getresgid, I32 a, I32 b, I32 c)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "getrusage", I32, getrusage, I32 a, I32 b)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "getrlimit", I32, getrlimit, I32 a, I32 b)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "setrlimit", I32, setrlimit, I32 a, I32 b)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "longjmp", void, longjmp, I32 a, U32 b)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "setjmp", I32, setjmp, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__errno_location", I32, wasi__errno_location)
void envLink()
void faasmLink()
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__faasm_push_state", void, __faasm_push_state, I32 keyPtr)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__faasm_push_state_partial", void, __faasm_push_state_partial, I32 keyPtr)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__faasm_push_state_partial_mask", void, __faasm_push_state_partial_mask, I32 keyPtr, I32 maskKeyPtr)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__faasm_pull_state", void, __faasm_pull_state, I32 keyPtr, I32 stateLen)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__faasm_lock_state_read", void, __faasm_lock_state_read, I32 keyPtr)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__faasm_unlock_state_read", void, __faasm_unlock_state_read, I32 keyPtr)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__faasm_lock_state_write", void, __faasm_lock_state_write, I32 keyPtr)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__faasm_unlock_state_write", void, __faasm_unlock_state_write, I32 keyPtr)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__faasm_write_state", void, __faasm_write_state, I32 keyPtr, I32 dataPtr, I32 dataLen)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__faasm_append_state", void, __faasm_append_state, I32 keyPtr, I32 dataPtr, I32 dataLen)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__faasm_read_appended_state", void, __faasm_read_appended_state, I32 keyPtr, I32 bufferPtr, I32 bufferLen, I32 nElems)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__faasm_clear_appended_state", void, __faasm_clear_appended_state, I32 keyPtr)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__faasm_write_state_offset", void, __faasm_write_state_offset, I32 keyPtr, I32 totalLen, I32 offset, I32 dataPtr, I32 dataLen)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__faasm_write_state_from_file", I32, __faasm_write_state_from_file, I32 keyPtr, I32 pathPtr)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__faasm_read_state", I32, __faasm_read_state, I32 keyPtr, I32 bufferPtr, I32 bufferLen)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__faasm_read_state_ptr", I32, __faasm_read_state_ptr, I32 keyPtr, I32 totalLen)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__faasm_read_state_offset", void, __faasm_read_state_offset, I32 keyPtr, I32 totalLen, I32 offset, I32 bufferPtr, I32 bufferLen)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__faasm_read_state_offset_ptr", I32, __faasm_read_state_offset_ptr, I32 keyPtr, I32 totalLen, I32 offset, I32 len)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__faasm_flag_state_dirty", void, __faasm_flag_state_dirty, I32 keyPtr, I32 totalLen)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__faasm_flag_state_offset_dirty", void, __faasm_flag_state_offset_dirty, I32 keyPtr, I32 totalLen, I32 offset, I32 len)
I32 _readInputImpl(I32 bufferPtr, I32 bufferLen)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__faasm_read_input", I32, __faasm_read_input, I32 bufferPtr, I32 bufferLen)
void _writeOutputImpl(I32 outputPtr, I32 outputLen)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__faasm_write_output", void, __faasm_write_output, I32 outputPtr, I32 outputLen)
void _readPythonInput(I32 buffPtr, I32 buffLen, const std::string &value)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__faasm_get_py_user", void, __faasm_get_py_user, I32 bufferPtr, I32 bufferLen)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__faasm_get_py_func", void, __faasm_get_py_func, I32 bufferPtr, I32 bufferLen)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__faasm_get_py_entry", void, __faasm_get_py_entry, I32 bufferPtr, I32 bufferLen)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__faasm_conf_flag", U32, __faasm_conf_flag, I32 keyPtr)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__faasm_backtrace", void, __faasm_backtrace, I32 depth)
static std::shared_ptr<PointToPointGroup> getPointToPointGroup()
static std::pair<uint32_t, faabric::util::SnapshotDataType> extractSnapshotDataType(I32 varType)
static faabric::util::SnapshotMergeOperation extractSnapshotMergeOp(I32 mergeOp)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__faasm_sm_reduce", void, __faasm_sm_reduce, I32 varPtr, I32 varType, I32 reduceOp, int currentBatch)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__faasm_sm_critical_local", void, __faasm_sm_critical_local)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__faasm_sm_critical_local_end", void, __faasm_sm_critical_local_end)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__faasm_migrate_point", void, __faasm_migrate_point, I32 entrypointFuncPtr, I32 entrypointFuncArg)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "setEmulatedMessageFromJson", I32, setEmulatedMessageFromJson, I32 msgPtr)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "emulatorGetAsyncResponse", I32, emulatorGetAsyncResponse)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "emulatorSetCallStatus", void, emulatorSetCallStatus, I32 success)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__faasm_host_interface_test", void, __faasm_host_interface_test, I32 testNum)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "fd_prestat_get", I32, wasi_fd_prestat_get, I32 fd, I32 prestatPtr)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "fd_prestat_dir_name", I32, wasi_fd_prestat_dir_name, I32 fd, I32 resPathPtr, I32 resPathLen)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "path_open", I32, wasi_path_open, I32 rootFd, I32 lookupFlags, I32 path, I32 pathLen, U32 openFlags, U64 rightsBase, U64 rightsInheriting, I32 fdFlags, I32 resFdPtr)
int doWasiDup(I32 fd)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "dup", I32, dup, I32 fd)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__wasi_fd_dup", I32, __wasi_fd_dup, I32 fd, I32 resFdPtr)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "fd_readdir", I32, wasi_fd_readdir, I32 fd, I32 buf, I32 bufLen, U64 startCookie, I32 resSizePtr)

This works a little like the normal Linux readdir, in that it will be called repeatedly to get the full listing of a directory.

The function should fill the read buffer until it’s reached the final “page” of results, at which point the returned size will be smaller than the read buffer.

I32 s__getdents64(I32 fd, I32 wasmDirentBuf, I32 wasmDirentBufLen)

This function is tricky to implement as it’s iterating through an unknown number of files in the directory. We will be running two loops, one to fill up the given buffer, and a nested loop to iterate through the native directory listing.

We try to be conservative but will throw an exception if things aren’t right. A bug here can be hard to find.

The musl implementation of readdir seems to require returning (-1 * errno) on error, not -1 as the man pages suggest.

WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "fd_close", I32, wasi_fd_close, I32 fd)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "fd_write", I32, wasi_fd_write, I32 fd, I32 iovecsPtr, I32 iovecCount, I32 resBytesWrittenPtr)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "fd_read", I32, wasi_fd_read, I32 fd, I32 iovecsPtr, I32 iovecCount, I32 resBytesRead)
I32 s__mkdir(I32 pathPtr, I32 mode)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "path_create_directory", I32, wasi_path_create_directory, I32 fd, I32 path, I32 pathLen)
I32 s__rename(I32 srcPtr, I32 destPtr)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "path_rename", I32, wasi_path_rename, I32 fd, I32 oldPath, I32 oldPathLen, I32 newFd, I32 newPath, I32 newPathLen)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "path_unlink_file", I32, wasi_path_unlink_file, I32 rootFd, I32 pathPtr, I32 pathLen)
I32 s__unlink(I32 pathPtr)
I32 s__access(I32 pathPtr, I32 mode)
I32 s__fstat64(I32 fd, I32 statBufPtr)
I32 s__lstat64(I32 pathPtr, I32 statBufPtr)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "fd_fdstat_get", I32, wasi_fd_fdstat_get, I32 fd, I32 statPtr)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "fd_fdstat_set_rights", I32, wasi_fd_fdstat_set_rights, I32 a, I64 b, I64 c)
I32 doFileStat(int fd, const std::string &relativePath, I32 statPtr)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "fd_filestat_get", I32, wasi_fd_filestat_get, I32 fd, I32 statPtr)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "path_filestat_get", I32, wasi_path_filestat_get, I32 fd, I32 lookupFlags, I32 path, I32 pathLen, I32 statPtr)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "path_filestat_set_times", I32, wasi_path_filestat_set_times, I32 fd, I32 lookupFlags, I32 path, I32 pathLen, I64 accessTimeStamp, I64 modTimeStamp, I32 fstFlags)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "fd_tell", I32, wasi_fd_tell, I32 fd, I32 resOffsetPtr)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "fd_seek", I32, wasi_fd_seek, I32 fd, I64 offset, I32 whence, I32 newOffsetPtr)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "fd_advise", I32, wasi_fd_advise, I32 fd, I64 offset, I64 len, I32 advice)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "ioctl", I32, ioctl, I32 a, I32 b, I32 c)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "puts", I32, puts, I32 strPtr)

Note here that we assume puts is called on a null-terminated string

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "putc", I32, putc, I32 c, I32 streamPtr)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "vfprintf", I32, vfprintf, I32 fd, U32 formatPtr, I32 argList)

fprintf can provide some useful debugging info so we can just spit it to stdout

I32 s__readlink(I32 pathPtr, I32 bufPtr, I32 bufLen)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "path_readlink", I32, wasi_path_readlink, I32 rootFd, I32 pathPtr, I32 pathLen, I32 buffPtr, I32 buffLen, I32 resBytesUsed)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "fd_fdstat_set_flags", I32, wasi_fd_fdstat_set_flags, I32 fd, I32 fdFlags)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "bzero", void, bzero, I32 wasmPtr, I32 len)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "explicit_bzero", void, explicit_bzero, I32 wasmPtr, I32 len)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__small_sprintf", I32, __small_sprintf, I32 a, I32 b, I32 c)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "fd_renumber", I32, wasi_fd_renumber, I32 fdOld, I32 fdNew)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "tmpfile", I32, tmpfile)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "umask", I32, umask, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "msync", I32, msync, I32 a, I32 b, I32 c)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "tempnam", I32, tempnam, I32 a, I32 b)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "memfd_create", I32, memfd_create, I32 a, I32 b)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "setgroups", I32, setgroups, I32 a, I32 b)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "fchdir", I32, s__fchdir, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "chmod", I32, s__chmod, I32 a, I32 b)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "fd_datasync", I32, wasi_fd_datasync, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "fd_pwrite", I32, wasi_fd_pwrite, I32 a, I32 b, I32 c, I64 d, I32 e)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "fd_pread", I32, wasi_fd_pread, I32 a, I32 b, I32 c, I64 d, I32 e)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "fd_filestat_set_size", I32, wasi_fd_filestat_set_size, I32 a, I64 b)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "fd_sync", I32, wasi_fd_sync, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "fd_allocate", I32, wasi_fd_allocate, I32 a, I64 b, I64 c)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "fd_filestat_set_times", I32, fd_filestat_set_times, I32 a, I64 b, I64 c, I32 d)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "path_link", I32, wasi_path_link, I32 a, I32 b, I32 c, I32 d, I32 e, I32 f, I32 g)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "path_symlink", I32, wasi_path_symlink, I32 a, I32 b, I32 c, I32 d, I32 e)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "path_remove_directory", I32, wasi_path_remove_directory, I32 a, I32 b, I32 c)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "lockf", I32, lockf, I32 a, I32 b, I64 c)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "strncat", I32, strncat, I32 a, I32 b, I32 c)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "realpath", I32, realpath, I32 a, U32 b)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "dirfd", I32, dirfd, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "poll", I32, poll, I32 a, I32 b, I32 c)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "sendfile", I32, sendfile, I32 out_fd, I32 in_fd, I32 offset, I32 count)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "fiprintf", I32, wasi_fiprintf, I32 a, I32 b, I32 c)
void ioLink()
std::string getModuleKey(const std::string &user, const std::string &func, const std::string &path)
static void setModuleSpecFeatures(IR::Module &module)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "_Unwind_RaiseException", I32, _Unwind_RaiseException, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "_Unwind_DeleteException", void, _Unwind_DeleteException, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__cxa_begin_catch", I32, __cxa_begin_catch, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__cxa_allocate_exception", I32, __cxa_allocate_exception, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__cxa_throw", void, __cxa_throw, I32 a, I32 b, I32 c)
void libcxxLink()
int32_t getModuleStackPointer(Runtime::Instance *module, Runtime::Context *context)
void mathsLink()
I32 s__madvise(I32 address, I32 numBytes, I32 advice)
I32 s__membarrier(I32 a)
std::shared_ptr<faabric::state::StateKeyValue> getStateKV(I32 keyPtr, size_t size)
std::shared_ptr<faabric::state::StateKeyValue> getStateKV(I32 keyPtr)
I32 doMmap(I32 addr, I32 length, I32 prot, I32 flags, I32 fd, I32 offset)
I32 s__mmap(I32 addr, I32 length, I32 prot, I32 flags, I32 fd, I32 offset)

Note that syscall 192 is mmap2, which has the same interface as mmap except that the final argument specifies the offset into the file in 4096-byte units (instead of bytes, as is done by mmap). Given that we ignore the offset we can just treat it like mmap

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "mmap", I32, wasi_mmap, I32 addr, I32 length, I32 prot, I32 flags, I32 fd, I64 offset)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "munmap", I32, wasi_munmap, I32 addr, I32 length)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__sbrk", I32, __sbrk, I32 increment)

Note that sbrk should only be called indirectly through musl. The required behaviour is:

  • brk(0) returns the current break

  • returns the new break if successful

  • returns -1 if there’s an issue and sets errno

Note that we assume the address is page-aligned and shrink memory if necessary.

I32 s__mprotect(I32 addrPtr, I32 len, I32 prot)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "shm_open", I32, shm_open, I32 a, I32 b, I32 c)
void memoryLink()
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "gettext", I32, s__gettext, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "dgettext", I32, s__dgettext, I32 a, I32 b)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "dcgettext", I32, s__dcgettext, I32 a, I32 b, I32 c)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "textdomain", I32, s__textdomain, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "bindtextdomain", I32, s__bindtextdomain, I32 a, I32 b)
void messagesLink()
bool isInPlace(U8 wasmPtr)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Init", I32, MPI_Init, I32 a, I32 b)

Sets up the MPI world. Arguments are argc/argv which are NULL, NULL in our case

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Get_version", I32, MPI_Get_version, I32 version, I32 subversion)

Returns the version of the standard corresponding to the current implementation.

TODO not implemented.

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Comm_size", I32, MPI_Comm_size, I32 comm, I32 resPtr)

Returns the number of ranks in the given communicator

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Comm_rank", I32, MPI_Comm_rank, I32 comm, I32 resPtr)

Returns the rank of the caller

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Comm_dup", I32, MPI_Comm_dup, I32 comm, I32 newComm)

Duplicates an existing communicator with all its cached information.

TODO not implemented.

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Comm_free", I32, MPI_Comm_free, I32 comm)

Mark a communicator object for deallocation

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Comm_split", I32, MPI_Comm_split, I32 comm, I32 color, I32 key, I32 newComm)

Creates new communicators based on colors and keys.

TODO not implemented.

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Comm_c2f", I32, MPI_Comm_c2f, I32 comm)

Returns a valid Fortran communicator handler

https://www.open-mpi.org/doc/v4.0/man3/MPI_Comm_c2f.3.php TODO not implemented

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Comm_f2c", I32, MPI_Comm_f2c, I32 fComm)

Returns a valid C communicator handler

https://www.open-mpi.org/doc/v4.0/man3/MPI_Comm_c2f.3.php TODO not implemented

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Send", I32, MPI_Send, I32 buffer, I32 count, I32 datatype, I32 destRank, I32 tag, I32 comm)

Sends a single point-to-point message

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Rsend", I32, MPI_Rsend, I32 buffer, I32 count, I32 datatype, I32 destRank, I32 tag, I32 comm)

Ready send: the user guarantees that a receive is already posted. TODO not implemented

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Isend", I32, MPI_Isend, I32 buffer, I32 count, I32 datatype, I32 destRank, I32 tag, I32 comm, I32 requestPtrPtr)

Sends a single async point-to-point message

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Get_count", I32, MPI_Get_count, I32 statusPtr, I32 datatype, I32 countPtr)

Returns the number of elements the given MPI_Status corresponds to.

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Recv", I32, MPI_Recv, I32 buffer, I32 count, I32 datatype, I32 sourceRank, I32 tag, I32 comm, I32 statusPtr)

Receives a single point-to-point message.

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Sendrecv", I32, MPI_Sendrecv, I32 sendBuf, I32 sendCount, I32 sendType, I32 destination, I32 sendTag, I32 recvBuf, I32 recvCount, I32 recvType, I32 source, I32 recvTag, I32 comm, I32 statusPtr)

Sends and receives a message.

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Irecv", I32, MPI_Irecv, I32 buffer, I32 count, I32 datatype, I32 sourceRank, I32 tag, I32 comm, I32 requestPtrPtr)

Receives a single asynchronous point-to-point message.

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Wait", I32, MPI_Wait, I32 requestPtrPtr, I32 status)

Waits for the asynchronous request to complete

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Waitall", I32, MPI_Waitall, I32 count, I32 requestArray, I32 statusArray)

Waits for all given communications to complete TODO not implemented

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Waitany", I32, MPI_Waitany, I32 count, I32 requestArray, I32 idx, I32 status)

Waits for any specified send or receive to complete TODO not implemented

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Abort", I32, MPI_Abort, I32 a, I32 b)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Finalize", I32, MPI_Finalize)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Probe", I32, MPI_Probe, I32 source, I32 tag, I32 comm, I32 statusPtr)

Populates the given status with info about an incoming message.

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Bcast", I32, MPI_Bcast, I32 buffer, I32 count, I32 datatype, I32 root, I32 comm)

Broadcasts a message. This is called by both senders and receivers of broadcasts.

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Barrier", I32, MPI_Barrier, I32 comm)

Barrier between all ranks in the given communicator. Called by every rank in the communicator.

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Scatter", I32, MPI_Scatter, I32 sendBuf, I32 sendCount, I32 sendType, I32 recvBuf, I32 recvCount, I32 recvType, I32 root, I32 comm)

Distributes an array of data between all ranks in the communicator

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Gather", I32, MPI_Gather, I32 sendBuf, I32 sendCount, I32 sendType, I32 recvBuf, I32 recvCount, I32 recvType, I32 root, I32 comm)

Pulls data from all ranks in a communicator into a single buffer.

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Allgather", I32, MPI_Allgather, I32 sendBuf, I32 sendCount, I32 sendType, I32 recvBuf, I32 recvCount, I32 recvType, I32 comm)

Each rank gathers data from all other ranks. Results in all seeing the same buffer.

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Allgatherv", I32, MPI_Allgatherv, I32 sendBuf, I32 sendCount, I32 sendType, I32 recvBuf, I32 recvCount, I32 dspls, I32 recvType, I32 comm)

Gathers data from all processes and delivers it to all. Each process may contribute a different amount of data.

TODO not implemented.

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Reduce", I32, MPI_Reduce, I32 sendBuf, I32 recvBuf, I32 count, I32 datatype, I32 op, I32 root, I32 comm)

Reduces data sent by all ranks in the communicator using the given operator.

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Reduce_scatter", I32, MPI_Reduce_scatter, I32 sendBuf, I32 recvBuf, I32 recvCount, I32 datatype, I32 op, I32 comm)

Combines values and scatters the results.

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Allreduce", I32, MPI_Allreduce, I32 sendBuf, I32 recvBuf, I32 count, I32 datatype, I32 op, I32 comm)

Reduces data from all ranks in the communicator into all ranks, i.e. an all-to-all reduce where each ends up with the same data.

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Scan", I32, MPI_Scan, I32 sendBuf, I32 recvBuf, I32 count, I32 datatype, I32 op, I32 comm)

Computes an inclusive scan (partial reduction). The operation returns, when run on process with rank i, the reduction of the values of processes 0, …, i (inclusive).

Reference implementation: https://github.com/open-mpi/ompi/blob/master/ompi/mpi/c/scan.c

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Alltoall", I32, MPI_Alltoall, I32 sendBuf, I32 sendCount, I32 sendType, I32 recvBuf, I32 recvCount, I32 recvType, I32 comm)

Sends an all-to-all message.

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Alltoallv", I32, MPI_Alltoallv, I32 sendBuf, I32 sendCount, I32 sdispls, I32 sendType, I32 recvBuf, I32 recvCount, I32 rdispls, I32 recvType, I32 comm)

All processes send different amount of data to, and receive different amount of data from, all processes.

TODO not implemented

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Get_processor_name", I32, MPI_Get_processor_name, I32 buf, I32 bufLen)

Returns the name of this host

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Type_size", I32, MPI_Type_size, I32 typePtr, I32 res)

Returns the size of the type.

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Alloc_mem", I32, MPI_Alloc_mem, I32 memSize, I32 info, I32 resPtrPtr)

Allocates memory on this host (equivalent to a malloc)

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Cart_create", I32, MPI_Cart_create, I32 commOld, I32 ndims, I32 dims, I32 periods, I32 reorder, I32 newCommPtrPtr)

Makes a new communicator to which Cartesian topology information has been attached. Note: In MPI, memory is allocated from within the function call, that’s why we allocate it here.

Reference implementation: https://github.com/open-mpi/ompi/blob/master/ompi/mca/topo/base/topo_base_cart_create.c

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Cart_rank", I32, MPI_Cart_rank, I32 comm, I32 coords, I32 rankPtr)

Determines process rank in communicator given Cartesian location.

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Cart_get", I32, MPI_Cart_get, I32 comm, I32 maxdims, I32 dims, I32 periods, I32 coords)

Retrieves the Cartesian topology information associated with a communicator.

MPI Topologies are pointless in a serverless environment. Therefore we return default values (2dim grid) basing on the current world size.

In particular we define a 2-dim grid with as many processors, leaving the rest as MPI_UNDEFINED.

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Cart_shift", I32, MPI_Cart_shift, I32 comm, I32 direction, I32 disp, I32 sourceRank, I32 destRank)

Returns the shifted source and destination ranks, given a shift direction and amount.

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Op_create", I32, MPI_Op_create, I32 userFn, I32 commute, I32 op)

Creates a user-defined combination function handle.

TODO not implemented.

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Op_free", I32, MPI_Op_free, I32 op)

Frees a user-defined combination function handle.

TODO not implemented.

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Win_create", I32, MPI_Win_create, I32 basePtr, I32 size, I32 dispUnit, I32 info, I32 comm, I32 winPtrPtr)

Creates a shared memory region (i.e. a chunk of Faasm state)

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Win_fence", I32, MPI_Win_fence, I32 assert, I32 winPtr)

Special type of barrier invoked to ensure all RMA operations have completed.

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Get", I32, MPI_Get, I32 recvBuf, I32 recvCount, I32 recvType, I32 sendRank, I32 sendOffset, I32 sendCount, I32 sendType, I32 winPtr)

One-sided get RDMA.

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Put", I32, MPI_Put, I32 sendBuf, I32 sendCount, I32 sendType, I32 recvRank, I32 recvOffset, I32 recvCount, I32 recvType, I32 winPtr)

One-sided write to shared memory.

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Win_free", I32, MPI_Win_free, I32 winPtr)

Cleans up the given window

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Win_get_attr", I32, MPI_Win_get_attr, I32 winPtr, I32 attrKey, I32 attrResPtrPtr, I32 flagResPtr)

Returns the value for a given attribute of a window.

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Free_mem", I32, MPI_Free_mem, I32 basePtr)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Request_free", I32, MPI_Request_free, I32 requestPtr)

Frees a communication request object. TODO not implemented

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Type_contiguous", I32, MPI_Type_contiguous, I32 count, I32 oldDatatypePtr, I32 newDatatypePtrPtr)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Type_free", I32, MPI_Type_free, I32 datatype)

Frees a data type

TODO not implemented.

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Type_commit", I32, MPI_Type_commit, I32 datatypePtrPtr)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "MPI_Wtime", F64, MPI_Wtime)
void mpiLink()
void setSockAddr(sockaddr nativeSockAddr, I32 addrPtr)

Writes changes to a native sockaddr back to a wasm sockaddr. This is important in several networking syscalls that receive responses and modify arguments in place

void setSockLen(socklen_t nativeValue, I32 wasmPtr)
I32 s__socketcall(I32 call, I32 argsPtr)

When properly isolated, functions will run in their own network namespace, therefore we can be relatively comfortable passing some of the syscalls straight through.

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "gethostbyname", I32, _gethostbyname, I32 hostnamePtr)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "gethostname", I32, gethostname, I32 buffer, I32 bufferLen)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "socket", I32, socket, I32 a, I32 b, I32 c)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "sock_accept", I32, sock_accept, I32 a, I32 b, I32 c)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "sock_send", I32, wasi_sock_send, I32 a, I32 b, I32 c, I32 d, I32 e)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "sock_recv", I32, wasi_sock_recv, I32 a, I32 b, I32 c, I32 d, I32 e, I32 f)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "sock_shutdown", I32, wasi_sock_shutdown, I32 a, I32 b)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "bind", I32, bind, I32 a, I32 b, I32 c)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "listen", I32, listen, I32 a, I32 b)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "setsockopt", I32, setsockopt, I32 a, I32 b, I32 c, I32 d, I32 e)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "accept", I32, accept, I32 a, I32 b, I32 c)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "inet_addr", I32, inet_addr, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "connect", I32, connect, I32 a, I32 b, I32 c)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "recvfrom", I32, recvfrom, I32 a, I32 b, I32 c, I32 d, I32 e, I32 f)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "sendto", I32, sendto, I32 a, I32 b, I32 c, I32 d, I32 e, I32 f)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "inet_ntoa", I32, inet_ntoa, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "getprotobyname", I32, getprotobyname, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "getservbyname", I32, s__getservbyname, I32 a, I32 b)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "gethostbyaddr", I32, s__gethostbyaddr, I32 a, I32 b, I32 c)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "getservbyport", I32, s__getservbyport, I32 a, I32 b)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "getsockname", I32, s__getsockname, I32 a, I32 b, I32 c)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "atoi", I32, atoi, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "htons", I32, _htons, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "ntohl", I32, _ntohl, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "ntohs", I32, _ntohs, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "htonl", I32, _htonl, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "inet_aton", I32, _inet_aton, I32 a, I32 b)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "shutdown", I32, _shutdown, I32 a, I32 b)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "inet_pton", I32, _inet_pton, I32 a, I32 b, I32 c)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "inet_ntop", I32, _inet_ntop, I32 a, I32 b, I32 c, I32 d)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "recv", I32, _recv, I32 a, I32 b, I32 c, I32 d)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "send", I32, _send, I32 a, I32 b, I32 c, I32 d)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "getsockopt", I32, getsockopt, I32 a, I32 b, I32 c, I32 d, I32 e)
void networkLink()
static std::shared_ptr<faabric::transport::PointToPointGroup> getExecutingPointToPointGroup()
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "omp_get_thread_num", I32, omp_get_thread_num)
Returns

the thread number, within its team, of the thread executing the function.

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "omp_get_num_threads", I32, omp_get_num_threads)
Returns

the number of threads currently in the team executing the parallel region from which it is called.

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "omp_get_max_threads", I32, omp_get_max_threads)

This function returns the max number of threads that can be used in a new team if no num_threads value is provided.

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "omp_get_level", I32, omp_get_level)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "omp_get_max_active_levels", I32, omp_get_max_active_levels)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "omp_set_max_active_levels", void, omp_set_max_active_levels, I32 maxLevels)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__kmpc_push_num_threads", void, __kmpc_push_num_threads, I32 loc, I32 globalTid, I32 numThreads)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "omp_set_num_threads", void, omp_set_num_threads, I32 numThreads)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__kmpc_global_thread_num", I32, __kmpc_global_thread_num, I32 loc)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "omp_get_wtime", F64, omp_get_wtime)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__kmpc_barrier", void, __kmpc_barrier, I32 loc, I32 globalTid)

Synchronization point at which threads in a parallel region will not execute beyond the omp barrier until all other threads in the team complete all explicit tasks in the region. Concepts used for reductions and split barriers.

Parameters
  • loc

  • global_tid

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__kmpc_critical", void, __kmpc_critical, I32 loc, I32 globalTid, I32 crit)

Enter code protected by a critical construct. This function blocks until the thread can enter the critical section.

Parameters
  • loc – source location information.

  • global_tid – global thread number.

  • crit – identity of the critical section. This could be a pointer to a lock associated with the critical section, or some other suitably unique value. The lock is not used because Faasm needs to control the locking mechanism for the team.

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__kmpc_end_critical", void, __kmpc_end_critical, I32 loc, I32 globalTid, I32 crit)

Exits code protected by a critical construct, releasing the held lock. This function blocks until the thread can enter the critical section.

Parameters
  • loc – source location information.

  • global_tid – global thread number.

  • crit – compiler lock. See __kmpc_critical for more information

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__kmpc_flush", void, __kmpc_flush, I32 loc)

The omp flush directive identifies a point at which the compiler ensures that all threads in a parallel region have the same view of specified objects in memory. Like clang here we use a fence, but this semantic might not be suited for distributed work. People doing distributed DSM OMP synch the page there.

Parameters

loc – Source location info

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__kmpc_master", I32, __kmpc_master, I32 loc, I32 globalTid)

Note: we only ensure the master section is run once, but do not handle assigning to the master section.

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__kmpc_end_master", void, __kmpc_end_master, I32 loc, I32 globalTid)

Only called by the thread executing the master region.

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__kmpc_single", I32, __kmpc_single, I32 loc, I32 globalTid)

Test whether to execute a single construct. There are no implicit barriers in the two “single” calls, rather the compiler should introduce an explicit barrier if it is required.

Parameters
  • loc

  • globalTid

Returns

1 if this thread should execute the single construct, zero otherwise.

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__kmpc_end_single", void, __kmpc_end_single, I32 loc, I32 globalTid)

See comment on __kmpc_single

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__kmpc_fork_call", void, __kmpc_fork_call, I32 locPtr, I32 nSharedVars, I32 microtaskPtr, I32 sharedVarPtrs)

The LLVM version of this function is implemented in the openmp source at: https://github.com/llvm/llvm-project/blob/main/openmp/runtime/src/kmp_csupport.cpp

It calls into __kmp_fork call to do most of the work, which is here: https://github.com/llvm/llvm-project/blob/main/openmp/runtime/src/kmp_runtime.cpp

The structs passed in are defined in this file: https://github.com/llvm/llvm-project/blob/main/openmp/runtime/src/kmp.h

Arguments:

  • locPtr = pointer to the source location info (type ident_t)

  • nSharedVars = number of non-global shared variables

  • microtaskPtr = function pointer for the microtask itself (microtask_t)

  • sharedVarPtrs = pointer to an array of pointers to the non-global shared variables

NOTE: the non-global shared variables include:

  • those listed in a shared() directive

  • those listed in a reduce() directive

template<typename T>
void for_static_init(I32 schedule, I32 *lastIter, T *lower, T *upper, T *stride, T incr, T chunk)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__kmpc_for_static_init_4", void, __kmpc_for_static_init_4, I32 loc, I32 gtid, I32 schedule, I32 lastIterPtr, I32 lowerPtr, I32 upperPtr, I32 stridePtr, I32 incr, I32 chunk)

The functions compute the upper and lower bounds and strides to be used for the set of iterations to be executed by the current thread.

The guts of the implementation in openmp can be found in __kmp_for_static_init in runtime/src/kmp_sched.cpp

See sched_type for supported scheduling.

Parameters
  • loc – Source code location

  • gtid – Global thread id of this thread

  • schedule – Scheduling type for the parallel loop

  • lastIterPtr – Pointer to the “last iteration” flag (boolean)

  • lowerPtr – Pointer to the lower bound

  • upperPtr – Pointer to the upper bound of loop chunk

  • stridePtr – Pointer to the stride for parallel loop

  • incr – Loop increment

  • chunk – The chunk size for the parallel loop

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__kmpc_for_static_init_8", void, __kmpc_for_static_init_8, I32 loc, I32 gtid, I32 schedule, I32 lastIterPtr, I32 lowerPtr, I32 upperPtr, I32 stridePtr, I64 incr, I64 chunk)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__kmpc_for_static_fini", void, __kmpc_for_static_fini, I32 loc, I32 gtid)
void startReduceCritical(faabric::Message *msg, std::shared_ptr<threads::Level> level, int32_t numReduceVars, int32_t reduceVarPtrs, int32_t reduceVarsSize)

Called to start a reduction.

void endReduceCritical(faabric::Message *msg, bool barrier)

Called to finish off a reduction.

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__kmpc_reduce", I32, __kmpc_reduce, I32 loc, I32 gtid, I32 numReduceVars, I32 reduceVarsSize, I32 reduceVarPtrs, I32 reduceFunc, I32 lockPtr)

This function is called to start the critical section required to perform the reduction operation by each thread. It will then call __kmpc_end_reduce (and its nowait equivalent), when it’s finished.

It seems that in our case, always returning 1 for both kmpc_reduce and kmpc_reduce_nowait gets the right result.

In the OpenMP source we can see a more varied set of return values, but these are for cases we don’t yet support (notably teams): https://github.com/llvm/llvm-project/blob/main/openmp/runtime/src/kmp_csupport.cpp

Note that the reduce vars passed into this function are the LOCAL copies on the thread’s own stack used to hold intermediate results. There is apparently no way to get a reference to the final destination of the reduction result in this function, that is only known in kmpc_fork_call.

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__kmpc_reduce_nowait", I32, __kmpc_reduce_nowait, I32 loc, I32 gtid, I32 numReduceVars, I32 reduceVarsSize, I32 reduceVarPtrs, I32 reduceFunc, I32 lockPtr)

See __kmpc_reduce

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__kmpc_end_reduce", void, __kmpc_end_reduce, I32 loc, I32 gtid, I32 lck)

Finalises a blocking reduce, called by all threads.

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__kmpc_end_reduce_nowait", void, __kmpc_end_reduce_nowait, I32 loc, I32 gtid, I32 lck)

Finalises a non-blocking reduce, called by all threads

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "omp_get_num_devices", int, omp_get_num_devices)

Get the number of devices (different CPU sockets or machines) available to that user

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "omp_set_default_device", void, omp_set_default_device, int defaultDeviceNumber)

Switches between local and remote threads.

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__atomic_load", void, __atomic_load, I32 a, I32 b, I32 c, I32 d)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__atomic_compare_exchange", I32, ___atomic_compare_exchange, I32 a, I32 b, I32 c, I32 d, I32 e, I32 f)
void ompLink()
I32 s__fork()
I32 s__waitpid(I32 pid, I32 statusPtr, I32 options)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "fork", I32, fork)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "chdir", I32, s__chdir, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "execve", I32, s__execve, I32 a, I32 b, I32 c)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "execv", I32, s__execv, I32 a, I32 b)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "kill", I32, s__kill, I32 a, I32 b)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "wait", I32, s__wait, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "pclose", I32, s__pclose, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "pipe", I32, s__pipe, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "popen", I32, s__popen, I32 a, I32 b)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "raise", I32, s__raise, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "system", I32, s__system, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "waitpid", I32, s__pid, I32 pid, I32 statusPtr, I32 options)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "openpty", I32, openpty, I32 a, I32 b, I32 c, I32 d, I32 e)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "forkpty", I32, forkpty, I32 a, I32 b, I32 c, I32 d)
void processLink()
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "getpriority", I32, getpriority, I32 a, I32 b)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "setpriority", I32, setpriority, I32 a, I32 b, I32 c)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "sched_yield", I32, wasi_sched_yield)
void schedulingLink()
I32 s__sigaction(I32 a, I32 b, I32 c)
I32 s__sigemptyset(I32 a)
I32 s__siginterrupt(I32 a, I32 b)
I32 s__rt_sigprocmask(I32 how, I32 sigSetPtr, I32 oldSetPtr, I32 sigsetsize)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "signal", I32, signal, I32 a, I32 b)
void signalsLink()
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "syscall", I32, syscall, I32 syscallNo, I32 argsPtr)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__syscall", I32, __syscall, I32 syscallNo, I32 argsPtr)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__syscall0", I32, __syscall0, I32 syscallNo)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__syscall1", I32, __syscall1, I32 syscallNo, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__syscall2", I32, __syscall2, I32 syscallNo, I32 a, I32 b)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__syscall3", I32, __syscall3, I32 syscallNo, I32 a, I32 b, I32 c)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__syscall4", I32, __syscall4, I32 syscallNo, I32 a, I32 b, I32 c, I32 d)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__syscall5", I32, __syscall5, I32 syscallNo, I32 a, I32 b, I32 c, I32 d, I32 e)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__syscall6", I32, __syscall6, I32 syscallNo, I32 a, I32 b, I32 c, I32 d, I32 e, I32 f)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__syscall7", I32, __syscall7, I32 syscallNo, I32 a, I32 b, I32 c, I32 d, I32 e, I32 f, I32 g)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "__syscall_cp", I32, __syscall_cp, I32 syscallNo, I32 a, I32 b, I32 c, I32 d, I32 e, I32 f)
I32 executeSyscall(int syscallNumber, int a, int b, int c, int d, int e, int f, int g)
void linkHook()
void getBytesFromWasm(int32_t dataPtr, int32_t dataLen, uint8_t *buffer)
std::vector<uint8_t> getBytesFromWasm(int32_t dataPtr, int32_t dataLen)
std::string getStringFromWasm(int32_t strPtr)
std::pair<std::string, std::string> getUserKeyPairFromWasm(int32_t keyPtr)
std::string getMaskedPathFromWasm(int32_t strPtr)
sockaddr getSockAddr(int32_t addrPtr)
void writeNativeStatToWasmStat(struct ::stat64 *nativeStatPtr, int32_t wasmStatPtr)
std::vector<iovec> wasmIovecsToNativeIovecs(int32_t wasmIovecPtr, int32_t wasmIovecCount)
std::vector<iovec> wasiIovecsToNativeIovecs(int32_t wasiIovecPtr, int32_t wasiIovecCount)
std::shared_ptr<faabric::state::StateKeyValue> getStateKV(int32_t keyPtr, size_t size)
std::shared_ptr<faabric::state::StateKeyValue> getStateKV(int32_t keyPtr)
int32_t s__access(int32_t pathPtr, int32_t mode)
int32_t s__clock_gettime(int32_t clockId, int32_t timespecPtr)
int32_t s__close(int32_t fd)
int32_t s__dup(int32_t oldFd)
int32_t s__exit(int32_t a, int32_t b)
int32_t s__fcntl64(int32_t fd, int32_t cmd, int32_t c)
int32_t s__waitpid(int32_t pid, int32_t statusPtr, int32_t options)
int32_t s__fstat64(int32_t fd, int32_t statBufPtr)
int32_t s__futex(int32_t uaddrPtr, int32_t futex_op, int32_t val, int32_t timeoutPtr, int32_t uaddr2Ptr, int32_t other)
int32_t s__getdents64(int32_t fd, int32_t wasmDirentBuf, int32_t wasmDirentBufLen)
int32_t s__getrandom(int32_t bufPtr, int32_t bufLen, int32_t flags)
int32_t s__gettimeofday(int32_t tvPtr, int32_t tzPtr)
int32_t s__ioctl(int32_t fd, int32_t request, int32_t argPtr, int32_t d, int32_t e, int32_t f)
int32_t s__llseek(int32_t fd, int32_t offsetHigh, int32_t offsetLow, int32_t resultPtr, int32_t whence)
int32_t s__lstat64(int32_t pathPtr, int32_t statBufPtr)
int32_t s__madvise(int32_t address, int32_t numBytes, int32_t advice)
int32_t s__membarrier(int32_t a)
int32_t s__mkdir(int32_t pathPtr, int32_t mode)
int32_t s__mmap(int32_t addr, int32_t length, int32_t prot, int32_t flags, int32_t fd, int32_t offset)
int32_t s__mprotect(int32_t addrPtr, int32_t len, int32_t prot)
int32_t s__nanosleep(int32_t reqPtr, int32_t remPtr)
int32_t s__open(int32_t pathPtr, int32_t flags, int32_t mode)
int32_t s__poll(int32_t fdsPtr, int32_t nfds, int32_t timeout)
int32_t s__read(int32_t fd, int32_t bufPtr, int32_t bufLen)
int32_t s__readlink(int32_t pathPtr, int32_t bufPtr, int32_t bufLen)
int32_t s__readv(int32_t fd, int32_t iovecPtr, int32_t iovecCount)
int32_t s__rename(int32_t srcPtr, int32_t destPtr)
int32_t s__rt_sigprocmask(int32_t how, int32_t sigSetPtr, int32_t oldSetPtr, int32_t sigsetsize)
int32_t s__sched_getaffinity(int32_t pid, int32_t cpuSetSize, int32_t maskPtr)
int32_t s__sigaction(int32_t a, int32_t b, int32_t c)
int32_t s__sigemptyset(int32_t a)
int32_t s__siginterrupt(int32_t a, int32_t b)
int32_t s__socketcall(int32_t call, int32_t argsPtr)
int32_t s__stat64(int32_t pathPtr, int32_t statBufPtr)
int32_t s__unlink(int32_t pathPtr)
int32_t s__write(int32_t fd, int32_t bufPtr, int32_t bufLen)
int32_t s__writev(int32_t fd, int32_t iov, int32_t iovcnt)
void threadsLink()
void timingLink()
void wasiLink()
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "pthread_create", I32, pthread_create, I32 pthreadPtr, I32 attrPtr, I32 entryFunc, I32 argsPtr)

We intercept the pthread API at a high level, hence we control the whole lifecycle. For this reason, we mostly ignore the contents of the pthread struct and pthread attrs.

We just use the int value of the pthread pointer to act as its ID (to be passed around the different pthread functions).

In the “chain” threading mode, we spawn threads as chained function calls, which may get executed on another host. To enable this we create a zygote from which these “thread” calls can be spawned on another host.

Parameters
  • pthreadPtr – - pointer to the pthread struct

  • attrPtr – - pointer to the pthread attr struct

  • entryFunc – - function table index for the entrypoint

  • argsPtr – - args pointer for the function

WAVM_DEFINE_INTRINSIC_FUNCTION (env, "pthread_join", I32, pthread_join, I32 pthreadPtr, I32 resPtrPtr)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "pthread_exit", void, pthread_exit, I32 code)
I32 s__futex(I32 uaddrPtr, I32 futex_op, I32 val, I32 timeoutPtr, I32 uaddr2Ptr, I32 other)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "pthread_mutex_init", I32, pthread_mutex_init, I32 mx, I32 attr)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "pthread_mutex_lock", I32, pthread_mutex_lock, I32 mx)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "pthread_mutex_trylock", I32, s__pthread_mutex_trylock, I32 mx)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "pthread_mutex_unlock", I32, pthread_mutex_unlock, I32 mx)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "pthread_mutex_destroy", I32, pthread_mutex_destroy, I32 mx)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "pthread_mutexattr_init", I32, pthread_mutexattr_init, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "pthread_mutexattr_destroy", I32, pthread_mutexattr_destroy, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "pthread_cond_init", I32, pthread_cond_init, I32 a, I32 b)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "pthread_cond_signal", I32, pthread_cond_signal, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "pthread_self", I32, pthread_self)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "pthread_key_create", I32, s__pthread_key_create, I32 a, I32 b)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "pthread_key_delete", I32, s__pthread_key_delete, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "pthread_getspecific", I32, s__pthread_getspecific, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "pthread_setspecific", I32, s__pthread_setspecific, I32 a, I32 b)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "pthread_cond_destroy", I32, pthread_cond_destroy, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "pthread_cond_broadcast", I32, pthread_cond_broadcast, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "pthread_equal", I32, pthread_equal, I32 a, I32 b)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "pthread_cond_timedwait", I32, pthread_cond_timedwait, I32 a, I32 b, I32 c)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "pthread_cond_wait", I32, pthread_cond_wait, I32 a, I32 b)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "pthread_attr_init", I32, s__pthread_attr_init, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "pthread_attr_setstacksize", I32, s__pthread_attr_setstacksize, I32 a, I32 b)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "pthread_attr_destroy", I32, s__pthread_attr_destroy, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "pthread_detach", I32, s__pthread_detach, I32 a)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "pthread_once", I32, s__pthread_once, I32 a, I32 b)
I32 s__clock_gettime(I32 clockId, I32 timespecPtr)
I32 s__gettimeofday(int tvPtr, int tzPtr)

As specified in the gettimeofday man page, use of the timezone struct is obsolete and hence not supported here

I32 s__nanosleep(I32 reqPtr, I32 remPtr)

Allow sleep for now

WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "poll_oneoff", I32, wasi_poll_oneoff, I32 subscriptionsPtr, I32 eventsPtr, I32 nSubs, I32 resNEvents)
WAVM_DEFINE_INTRINSIC_FUNCTION (env, "utime", I32, s__utime, I32 a, I32 b)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "clock_time_get", I32, wasi_clock_time_get, I32 clockId, I64 precision, I32 resultPtr)
WAVM_DEFINE_INTRINSIC_FUNCTION (wasi, "clock_res_get", I32, wasi_clock_res_get, I32 a, I32 b)
void getBytesFromWasm(I32 dataPtr, I32 dataLen, uint8_t *buffer)
std::vector<uint8_t> getBytesFromWasm(I32 dataPtr, I32 dataLen)
std::string getStringFromWasm(I32 strPtr)
std::pair<std::string, std::string> getUserKeyPairFromWasm(I32 keyPtr)
std::string getMaskedPathFromWasm(I32 strPtr)
sockaddr getSockAddr(I32 addrPtr)

Translates a wasm sockaddr into a native sockaddr

void writeNativeStatToWasmStat(struct ::stat64 *nativeStatPtr, I32 wasmStatPtr)

Translates a native stat to a wasm stat

std::vector<::iovec> wasmIovecsToNativeIovecs(I32 wasmIovecPtr, I32 wasmIovecCount)
std::vector<::iovec> wasiIovecsToNativeIovecs(I32 wasiIovecPtr, I32 wasiIovecCount)
static void instantiateBaseModules()

Variables

std::unordered_map<uint32_t, std::shared_ptr<wasm::EnclaveWasmModule>> moduleMap
std::mutex moduleMapMutex
static uint8_t wamrHeapBuffer[FAASM_SGX_WAMR_HEAP_SIZE]
static NativeSymbol ns[] = {REG_NATIVE_FUNC(dlopen, "($i)i"), REG_NATIVE_FUNC(dlsym, "(*$)i"), REG_NATIVE_FUNC(dlclose, "(*)i"),}
static NativeSymbol ns[] = {REG_NATIVE_FUNC(getrlimit, "(ii)i"),}
static NativeSymbol wasiNs[] = {REG_WASI_NATIVE_FUNC(args_get, "(**)i"), REG_WASI_NATIVE_FUNC(args_sizes_get, "(**)i"), REG_WASI_NATIVE_FUNC(environ_get, "(**)i"), REG_WASI_NATIVE_FUNC(environ_sizes_get, "(**)i"), REG_WASI_NATIVE_FUNC(proc_exit, "(i)"), REG_WASI_NATIVE_FUNC(random_get, "(*~)i"),}
static NativeSymbol ns[] = {REG_NATIVE_FUNC(__faasm_append_state, "(**i)"), REG_NATIVE_FUNC(__faasm_await_call, "(i)i"), REG_NATIVE_FUNC(__faasm_chain_name, "($$i)i"), REG_NATIVE_FUNC(__faasm_chain_ptr, "(i$i)i"), REG_NATIVE_FUNC(__faasm_host_interface_test, "(i)"), REG_NATIVE_FUNC(__faasm_migrate_point, "(ii)"), REG_NATIVE_FUNC(__faasm_pull_state, "(*i)"), REG_NATIVE_FUNC(__faasm_push_state, "(*)"), REG_NATIVE_FUNC(__faasm_read_appended_state, "(**ii)"), REG_NATIVE_FUNC(__faasm_read_input, "($i)i"), REG_NATIVE_FUNC(__faasm_write_output, "($i)"),}
static NativeSymbol ns[] = {REG_NATIVE_FUNC(__wasi_fd_dup, "(i*)i"), REG_NATIVE_FUNC(dup, "(i)i"), REG_NATIVE_FUNC(getpwnam, "(i)i"), REG_NATIVE_FUNC(sendfile, "(iiii)i"), REG_NATIVE_FUNC(tempnam, "(ii)i"),}
static NativeSymbol wasiNs[] = {REG_WASI_NATIVE_FUNC(fd_allocate, "(iII)i"), REG_WASI_NATIVE_FUNC(fd_close, "(i)i"), REG_WASI_NATIVE_FUNC(fd_fdstat_get, "(i*)i"), REG_WASI_NATIVE_FUNC(fd_fdstat_set_flags, "(ii)i"), REG_WASI_NATIVE_FUNC(fd_fdstat_set_rights, "(iII)i"), REG_WASI_NATIVE_FUNC(fd_filestat_get, "(i*)i"), REG_WASI_NATIVE_FUNC(fd_filestat_set_size, "(iI)i"), REG_WASI_NATIVE_FUNC(fd_pread, "(i*iI*)i"), REG_WASI_NATIVE_FUNC(fd_prestat_dir_name, "(i*~)i"), REG_WASI_NATIVE_FUNC(fd_prestat_get, "(i*)i"), REG_WASI_NATIVE_FUNC(fd_read, "(i*i*)i"), REG_WASI_NATIVE_FUNC(fd_readdir, "(i*~I*)i"), REG_WASI_NATIVE_FUNC(fd_pwrite, "(i*iI*)i"), REG_WASI_NATIVE_FUNC(fd_seek, "(iIi*)i"), REG_WASI_NATIVE_FUNC(fd_sync, "(i)i"), REG_WASI_NATIVE_FUNC(fd_tell, "(i*)i"), REG_WASI_NATIVE_FUNC(fd_write, "(i*i*)i"), REG_WASI_NATIVE_FUNC(path_create_directory, "(i*~)i"), REG_WASI_NATIVE_FUNC(path_filestat_get, "(ii*~*)i"), REG_WASI_NATIVE_FUNC(path_filestat_set_times, "(ii*~IIi)i"), REG_WASI_NATIVE_FUNC(path_link, "(ii*~i*~)i"), REG_WASI_NATIVE_FUNC(path_open, "(ii*~iIIi*)i"), REG_WASI_NATIVE_FUNC(path_readlink, "(i*~*~*)i"), REG_WASI_NATIVE_FUNC(path_remove_directory, "(i*~)i"), REG_WASI_NATIVE_FUNC(path_rename, "(i*~i*~)i"), REG_WASI_NATIVE_FUNC(path_symlink, "(*~i*~)i"), REG_WASI_NATIVE_FUNC(path_unlink_file, "(i*~)i"),}
static NativeSymbol ns[] = {REG_NATIVE_FUNC(__sbrk, "(i)i"), REG_NATIVE_FUNC(mmap, "(iiiiiI)i"), REG_NATIVE_FUNC(munmap, "(ii)i"),}
static thread_local MpiContext executingContext
static thread_local std::unique_ptr<WamrMpiContextWrapper> ctx = nullptr
static NativeSymbol ns[]
static NativeSymbol ns[] = {REG_NATIVE_FUNC(getpid, "()i"), REG_NATIVE_FUNC(pclose, "(i)i"), REG_NATIVE_FUNC(popen, "(ii)i"), REG_NATIVE_FUNC(raise, "(i)i"), REG_NATIVE_FUNC(system, "(i)i"),}
static NativeSymbol ns[] = {REG_NATIVE_FUNC(pthread_create, "(iiii)i"), REG_NATIVE_FUNC(pthread_join, "(ii)i"), REG_NATIVE_FUNC(pthread_once, "(ii)i"), REG_NATIVE_FUNC(pthread_mutex_init, "(ii)i"), REG_NATIVE_FUNC(pthread_mutex_lock, "(i)i"), REG_NATIVE_FUNC(pthread_mutex_unlock, "(i)i"), REG_NATIVE_FUNC(pthread_mutex_destroy, "(i)i"), REG_NATIVE_FUNC(pthread_cond_init, "(ii)i"), REG_NATIVE_FUNC(pthread_cond_signal, "(i)i"), REG_NATIVE_FUNC(pthread_cond_wait, "(ii)i"), REG_NATIVE_FUNC(pthread_cond_broadcast, "(i)i"), REG_NATIVE_FUNC(pthread_cond_destroy, "(i)i"), REG_NATIVE_FUNC(pthread_mutexattr_init, "(i)i"), REG_NATIVE_FUNC(pthread_mutexattr_destroy, "(i)i"), REG_NATIVE_FUNC(pthread_equal, "(ii)i"),}
static NativeSymbol ns[] = {REG_NATIVE_FUNC(signal, "(ii)i"),}
static NativeSymbol ns[] = {REG_NATIVE_FUNC(__faasm_read_state, "($$i)i"), REG_NATIVE_FUNC(__faasm_read_state_ptr, "($i)i"), REG_NATIVE_FUNC(__faasm_write_state, "($$i)"), REG_NATIVE_FUNC(__faasm_push_state, "($)"),}
static NativeSymbol ns[] = {REG_NATIVE_FUNC(__cxa_allocate_exception, "(i)i"), REG_NATIVE_FUNC(__cxa_throw, "(iii)"), REG_NATIVE_FUNC(shm_open, "($ii)i"), REG_NATIVE_FUNC(syscall, "(ii)i"),}
static NativeSymbol wasiNs[] = {REG_WASI_NATIVE_FUNC(clock_time_get, "(iI*)i"), REG_WASI_NATIVE_FUNC(poll_oneoff, "(**i*)i"),}
static bool wamrInitialised = false
static std::mutex wamrGlobalsMutex
static thread_local std::stack<WasmExecutionContext*> contexts
static thread_local faabric::mpi::MpiContext executingContext
static thread_local std::unique_ptr<ContextWrapper> ctx = nullptr
static Runtime::Instance *baseEnvModule = nullptr
static Runtime::Instance *baseWasiModule = nullptr
std::mutex baseModuleMx
class ContextWrapper

Convenience wrapper around the MPI context for use in the syscalls in this file.

Public Functions

inline explicit ContextWrapper()
inline void checkMpiComm(I32 wasmPtr)
inline faabric_datatype_t *getFaasmDataType(I32 wasmPtr)
inline void writeFaasmRequestId(I32 requestPtrPtr, I32 requestId)

We use a trick here to avoid allocating extra memory. Rather than create an actual struct for the MPI_Request, we just use the pointer to hold the value of its ID

inline I32 getFaasmRequestId(I32 requestPtrPtr)

This uses the same trick, where we read the value of the pointer as the request ID.

inline faabric_info_t *getFaasmInfoType(I32 wasmPtr)
inline faabric_op_t *getFaasmOp(I32 wasmOp)
template<typename T>
inline void writeMpiResult(I32 resPtr, T result)

Public Members

WAVMWasmModule *module
Runtime::Memory *memory
MpiWorld &world
int rank
class EnclaveInterface : public wasm::WasmModule

Public Functions

explicit EnclaveInterface()
~EnclaveInterface() override
virtual void doBindToFunction(faabric::Message &msg, bool cache) override
bool unbindFunction()
virtual int32_t executeFunction(faabric::Message &msg) override
virtual size_t getMemorySizeBytes() override
virtual size_t getMaxMemoryPages() override
virtual uint8_t *getMemoryBase() override
class EnclaveWasmModule : public WAMRModuleMixin<EnclaveWasmModule>

Public Functions

EnclaveWasmModule()
~EnclaveWasmModule()
bool loadWasm(void *wasmOpCodePtr, uint32_t wasmOpCodeSize)
bool callFunction(uint32_t argcIn, char **argvIn)
WASMModuleInstanceCommon *getModuleInstance()
uint32_t getArgc()
std::vector<std::string> getArgv()
size_t getArgvBufferSize()

Public Static Functions

static bool initialiseWAMRGlobally()
class IRModuleCache

Public Functions

IRModuleCache()
IR::Module &getModule(const std::string &user, const std::string &func, const std::string &path)
Runtime::ModuleRef getCompiledModule(const std::string &user, const std::string &func, const std::string &path)
U64 getSharedModuleTableSize(const std::string &user, const std::string &func, const std::string &path)
size_t getSharedModuleDataSize(const std::string &user, const std::string &func, const std::string &path)
bool isModuleCached(const std::string &user, const std::string &func, const std::string &path)
bool isCompiledModuleCached(const std::string &user, const std::string &func, const std::string &path)
void clear()
struct libffi_cif

Public Members

uint32_t abi
uint32_t nargs
uint32_t argTypesPtrPtr
uint32_t retTypePtr
uint32_t bytes
uint32_t flags
struct libffi_type

Public Members

uint32_t size
uint16_t alignment
uint16_t type
uint32_t elementsPtrPtr
class LoadedDynamicModule

Public Functions

bool validate()
void printDebugInfo(WAVM::Runtime::Context *context)
void log()

Public Members

std::string path
uint32_t memoryBottom = 0
uint32_t memoryTop = 0
uint32_t stackTop = 0
int32_t stackPointer = 0
uint32_t stackSize = 0
uint32_t dataBottom = 0
uint32_t dataTop = 0
uint32_t heapBottom = 0
uint32_t tableBottom = 0
uint32_t tableTop = 0
WAVM::Runtime::GCPointer<WAVM::Runtime::Instance> ptr = nullptr
class WamrMpiContextWrapper

Convenience wrapper around the MPI context for use in the syscalls in this file.

Public Functions

inline explicit WamrMpiContextWrapper()
inline void checkMpiComm(int32_t *wasmPtr) const
inline faabric_datatype_t *getFaasmDataType(int32_t *wasmPtr) const
inline void writeFaasmRequestId(int32_t *requestPtrPtr, int32_t requestId) const
inline int32_t getFaasmRequestId(int32_t *requestPtrPtr) const
inline bool isInPlace(int32_t *wasmPtr) const
inline faabric_op_t *getFaasmOp(int32_t *wasmPtr) const
template<typename T>
inline void writeMpiResult(int32_t *resPtr, T result)

Public Members

wasm::WAMRWasmModule *module
MpiWorld &world
int rank
class WAMRWasmModule : public wasm::WasmModule, public WAMRModuleMixin<WAMRWasmModule>

Public Functions

WAMRWasmModule()
explicit WAMRWasmModule(int threadPoolSizeIn)
~WAMRWasmModule()
virtual void reset(faabric::Message &msg, const std::string &snapshotKey) override
virtual void doBindToFunction(faabric::Message &msg, bool cache) override
virtual int32_t executeFunction(faabric::Message &msg) override
virtual void doThrowException(std::exception &e) override
void writeStringToWasmMemory(const std::string &strHost, char *strWasm)
void writeWasmEnvToWamrMemory(uint32_t *envOffsetsWasm, char *envBuffWasm)
void validateWasmOffset(uint32_t wasmOffset, size_t size)
virtual uint8_t *wasmPointerToNative(uint32_t wasmPtr) override
virtual uint32_t mmapFile(uint32_t fp, size_t length) override
virtual size_t getMemorySizeBytes() override
virtual uint8_t *getMemoryBase() override
virtual size_t getMaxMemoryPages() override
WASMModuleInstanceCommon *getModuleInstance()
std::vector<std::string> getArgv()

Public Static Functions

static void initialiseWAMRGlobally()
struct wasm_dirent64
#include <syscalls.h>

To double check this, work out which header from the sysroot is resolved Currently this is:

  • include/__struct_dirent.h

  • include/__typedef_ino_t.h

struct dirent { ino_t d_ino; # unsigned long long unsigned char d_type; char d_name[]; };

Public Members

uint64_t d_ino
uint8_t d_type
uint8_t d_name[]
struct wasm_faabric_win_t

Public Members

uint32_t worldId
uint32_t rank
uint32_t size
uint32_t wasmPtr
uint32_t dispUnit
struct wasm_iovec

Public Members

uint32_t iov_base
uint32_t iov_len
struct wasm_passwd
#include <syscalls.h>

Found in pwd.h.

Note that char pointers are uint32_t

Public Members

uint32_t pw_name
uint32_t pw_passwd
uint32_t pw_uid
uint32_t pw_gid
uint32_t pw_gecos
uint32_t pw_dir
uint32_t pw_shell
struct wasm_pthread
#include <syscalls.h>

Found in pthread_impl.h The “real” pthread struct has a lot of stuff in it. We only care about a subset of the fields that appear at the start, especially the pointer to itself, which allows references to be treated like pointers.

Public Members

int32_t selfPtr
struct wasm_sockaddr
#include <syscalls.h>

Socket-related struct (see https://beej.us/guide/bgnet/html/multi/sockaddr_inman.html)

Public Members

uint16_t sa_family
uint8_t sa_data[14]
struct wasm_stack_t
#include <syscalls.h>

Found in bits/signal.h stack_t is used in calls to sigaltstack, either to specify a new stack or to get details about the existing

Public Members

uint32_t ss_sp
int32_t ss_flags
int32_t ss_size
struct wasm_stat

Public Members

uint64_t st_dev
uint64_t st_ino
uint64_t st_nlink
uint32_t st_mode
uint32_t st_uid
uint32_t st_gid
uint32_t __pad0
uint64_t st_rdev
int64_t st_size
int32_t st_blksize
int64_t st_blocks
struct wasm_timespec st_atim
struct wasm_timespec st_mtim
struct wasm_timespec st_ctim
int64_t __unused[3]
struct wasm_timespec
#include <syscalls.h>

Any structs passed as arguments must be re-implemented here with the following mappings (respecting signed/ unsigned):

int64_t = int64_t/uint64_t short = int16_t/uint16_t long = int32_t/uint32_t int = int32_t/uint32_t char = uint8_t pointers = Uptr size_t = int32_t time_t = int64_t

You need to look at include/bits/alltypes.h in the relevant sysroot to get a lot of the types

Public Members

int64_t tv_sec
int32_t tv_nsec
struct wasm_timeval

Public Members

int64_t tv_sec
int32_t tv_usec
struct wasm_utsname
#include <syscalls.h>

Found in sys/utsname.h Used to convey system info via uname

Public Members

char sysname[65]
char nodename[65]
char release[65]
char version[65]
char machine[65]
char domainname[65]
struct wasm_winsize
#include <syscalls.h>

Found in ioctl.h Used to communicate size of the window we’re operating in

Public Members

uint16_t ws_row
uint16_t ws_col
uint16_t ws_xpixel
uint16_t ws_ypixel
class WasmEnvironment

Public Functions

WasmEnvironment()
void addEnv(const std::string &key, const std::string &value)
uint32_t getEnvCount()
uint32_t getEnvBufferSize()
std::vector<std::string> getVars()
std::string getEnv(const std::string &key)
void printDebugInfo()
class WasmExecutionContext

Public Functions

WasmExecutionContext(WasmModule *module)
~WasmExecutionContext()
WasmExecutionContext(const WasmExecutionContext&) = delete
WasmExecutionContext &operator=(const WasmExecutionContext&) = delete

Public Members

WasmModule *executingModule = nullptr
class WasmExitException : public exception

Public Functions

inline explicit WasmExitException(int exitCode)

Public Members

int exitCode
class WasmModule

Subclassed by wasm::EnclaveInterface, wasm::WAMRWasmModule, wasm::WAVMWasmModule

Public Functions

WasmModule()
explicit WasmModule(int threadPoolSizeIn)
virtual ~WasmModule()
virtual void reset(faabric::Message &msg, const std::string &snapshotKey)
void bindToFunction(faabric::Message &msg, bool cache = true)
int32_t executeTask(int threadPoolIdx, int msgIdx, std::shared_ptr<faabric::BatchExecuteRequest> req)
virtual int32_t executeFunction(faabric::Message &msg)
bool isBound()
std::string getBoundUser()
std::string getBoundFunction()
virtual void flush()
uint32_t getArgc()
uint32_t getArgvBufferSize()
virtual void writeArgvToMemory(uint32_t wasmArgvPointers, uint32_t wasmArgvBuffer)
virtual void writeWasmEnvToMemory(uint32_t envPointers, uint32_t envBuffer)
WasmEnvironment &getWasmEnvironment()
storage::FileSystem &getFileSystem()
virtual void doThrowException(std::exception &e)
ssize_t captureStdout(const struct ::iovec *iovecs, int iovecCount)
ssize_t captureStdout(const void *buffer)
std::string getCapturedStdout()
void clearCapturedStdout()
uint32_t getCurrentBrk()
virtual void setMemorySize(size_t nBytes)
uint32_t growMemory(size_t nBytes)
uint32_t shrinkMemory(size_t nBytes)
uint32_t mmapMemory(size_t nBytes)
virtual uint32_t mmapFile(uint32_t fp, size_t length)
void unmapMemory(uint32_t offset, size_t nBytes)
uint32_t createMemoryGuardRegion(uint32_t wasmOffset)
virtual uint32_t mapSharedStateMemory(const std::shared_ptr<faabric::state::StateKeyValue> &kv, long offset, uint32_t length)

Maps the given state into the module’s memory.

If we are dealing with a chunk of a larger state value, the host memory will be reserved for the full value, but only the necessary wasm pages will be created. Loading many chunks of the same value leads to fragmentation, but usually only one or two chunks are loaded per module.

To perform the mapping we need to ensure allocated memory is page-aligned.

virtual uint8_t *wasmPointerToNative(uint32_t wasmPtr)
virtual size_t getMemorySizeBytes()
virtual size_t getMaxMemoryPages()
virtual uint8_t *getMemoryBase()
std::shared_ptr<faabric::util::SnapshotData> getSnapshotData()
std::span<uint8_t> getMemoryView()
std::string snapshot(bool locallyRestorable = true)
void restore(const std::string &snapshotKey)
void queuePthreadCall(threads::PthreadCall call)
int awaitPthreadCall(faabric::Message *msg, int pthreadPtr)
std::vector<uint32_t> getThreadStacks()
std::shared_ptr<std::mutex> getPthreadMutex(uint32_t id)
std::shared_ptr<std::mutex> getOrCreatePthreadMutex(uint32_t id)
void addMergeRegionForNextThreads(uint32_t wasmPtr, size_t regionSize, faabric::util::SnapshotDataType dataType, faabric::util::SnapshotMergeOperation mergeOp)
std::vector<faabric::util::SnapshotMergeRegion> getMergeRegions()
void clearMergeRegions()
virtual int32_t executeOMPThread(int threadPoolIdx, uint32_t stackTop, faabric::Message &msg)
virtual int32_t executePthread(int threadPoolIdx, uint32_t stackTop, faabric::Message &msg)
virtual void printDebugInfo()
class WAVMModuleCache

Public Functions

std::pair<wasm::WAVMWasmModule&, faabric::util::SharedLock> getCachedModule(faabric::Message &msg)
std::string registerResetSnapshot(wasm::WasmModule &module, faabric::Message &msg)
void clear()
size_t getTotalCachedModuleCount()
class WAVMWasmModule : public wasm::WasmModule, private Resolver

Public Functions

WAVMWasmModule()
WAVMWasmModule(int threadPoolSizeIn)
WAVMWasmModule(const WAVMWasmModule &other)
WAVMWasmModule &operator=(const WAVMWasmModule &other)
~WAVMWasmModule()
virtual void doBindToFunction(faabric::Message &msg, bool cache) override
void bindToFunctionNoZygote(faabric::Message &msg)
virtual void reset(faabric::Message &msg, const std::string &snapshotKey) override
virtual void doThrowException(std::exception &e) override
virtual uint32_t mmapFile(uint32_t fd, size_t length) override
virtual uint8_t *wasmPointerToNative(uint32_t wasmPtr) override
virtual size_t getMemorySizeBytes() override
virtual size_t getMaxMemoryPages() override
virtual uint8_t *getMemoryBase() override
virtual void writeWasmEnvToMemory(uint32_t envPointers, uint32_t envBuffer) override
virtual void printDebugInfo() override
void executeWasmFunction(WAVM::Runtime::Function *func, WAVM::IR::FunctionType funcType, const std::vector<WAVM::IR::UntaggedValue> &arguments, WAVM::IR::UntaggedValue &result)
void executeWasmFunction(WAVM::Runtime::Function *func, const std::vector<WAVM::IR::UntaggedValue> &arguments, WAVM::IR::UntaggedValue &result)
void executeWasmFunction(WAVM::Runtime::Context *ctx, WAVM::Runtime::Function *func, const std::vector<WAVM::IR::UntaggedValue> &arguments, WAVM::IR::UntaggedValue &result)
virtual void writeArgvToMemory(uint32_t wasmArgvPointers, uint32_t wasmArgvBuffer) override
WAVM::Runtime::Function *getFunctionFromPtr(int funcPtr) const
bool resolve(const std::string &moduleName, const std::string &name, WAVM::IR::ExternType type, WAVM::Runtime::Object *&resolved) override
int32_t getGlobalI32(const std::string &globalName, WAVM::Runtime::Context *context)
std::map<std::string, std::string> buildDisassemblyMap()
int dynamicLoadModule(const std::string &path, WAVM::Runtime::Context *context)
uint32_t getDynamicModuleFunction(int handle, const std::string &funcName)
int getDynamicModuleCount()
uint32_t addFunctionToTable(WAVM::Runtime::Object *exportedFunc) const
int getNextMemoryBase()
int getNextStackPointer()
int getNextTableBase()
int getFunctionOffsetFromGOT(const std::string &funcName)
int getDataOffsetFromGOT(const std::string &name)
virtual int32_t executeFunction(faabric::Message &msg) override
virtual int32_t executeOMPThread(int threadPoolIdx, uint32_t stackTop, faabric::Message &msg) override
virtual int32_t executePthread(int threadPoolIdx, uint32_t stackTop, faabric::Message &msg) override

Public Members

WAVM::Runtime::GCPointer<WAVM::Runtime::Memory> defaultMemory
WAVM::Runtime::GCPointer<WAVM::Runtime::Table> defaultTable
WAVM::Runtime::GCPointer<WAVM::Runtime::Context> executionContext
WAVM::Runtime::GCPointer<WAVM::Runtime::Compartment> compartment

Public Static Functions

static void clearCaches()
static WAVM::Runtime::Function *getFunction(WAVM::Runtime::Instance *module, const std::string &funcName, bool strict)
static WAVM::Runtime::Context *createThreadContext(uint32_t stackTop, WAVM::Runtime::ContextRuntimeData *contextRuntimeData)