#pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define EXPORT __attribute__((visibility("default"))) #define IMPORT __attribute__((visibility("default"))) #define INLINE __attribute__((always_inline)) #define WEAK __attribute__((weak)) #ifndef PAGE_SIZE #define PAGE_SIZE (1 << 12) #endif #define PAGE_ALIGNED __attribute__((aligned(PAGE_SIZE))) /* For this family of macros, do NOT pass zero as the pow2 */ #define round_to_pow2(x, pow2) (((unsigned long)(x)) & (~((pow2)-1))) #define round_up_to_pow2(x, pow2) (round_to_pow2(((unsigned long)x) + (pow2)-1, (pow2))) #define round_to_page(x) round_to_pow2(x, PAGE_SIZE) #define round_up_to_page(x) round_up_to_pow2(x, PAGE_SIZE) /* Type alias's so I don't have to write uint32_t a million times */ typedef signed char i8; typedef unsigned char u8; typedef int16_t i16; typedef uint16_t u16; typedef int32_t i32; /* FIXME: per-module configuration? */ #define WASM_PAGE_SIZE (1024 * 64) /* 64KB */ #define WASM_START_PAGES (1 << 8) /* 16MB */ #define WASM_MAX_PAGES (1 << 15) /* 4GB */ #define WASM_STACK_SIZE (1 << 19) /* 512KB */ #define SBOX_MAX_MEM (1L << 32) /* 4GB */ /* These are per module symbols and I'd need to dlsym for each module. instead just use global constants, see above macros. The code generator compiles in the starting number of wasm pages, and the maximum number of pages If we try and allocate more than max_pages, we should fault */ // TODO: Should this be deleted? // extern uint32_t starting_pages; // extern uint32_t max_pages; /* The code generator also compiles in stubs that populate the linear memory and function table */ void populate_memory(void); void populate_table(void); /* memory also provides the table access functions */ #define INDIRECT_TABLE_SIZE (1 << 10) struct indirect_table_entry { uint32_t type_id; void * func_pointer; }; /* Cache of Frequently Accessed Members used to avoid pointer chasing */ struct sandbox_context_cache { struct indirect_table_entry *module_indirect_table; void * linear_memory_start; uint32_t linear_memory_size; }; extern __thread struct sandbox_context_cache local_sandbox_context_cache; /* TODO: LOG_TO_FILE logic is untested */ extern i32 runtime_log_file_descriptor; /* functions in the module to lookup and call per sandbox. */ typedef i32 (*mod_main_fn_t)(i32 a, i32 b); typedef void (*mod_glb_fn_t)(void); typedef void (*mod_mem_fn_t)(void); typedef void (*mod_tbl_fn_t)(void); typedef void (*mod_libc_fn_t)(i32, i32); /** * debuglog is a macro that behaves based on the macros DEBUG and LOG_TO_FILE * If DEBUG is not set, debuglog does nothing * If DEBUG is set and LOG_TO_FILE is set, debuglog prints to the logfile defined in runtime_log_file_descriptor * If DEBUG is set adn LOG_TO_FILE is not set, debuglog prints to STDOUT */ #ifdef DEBUG #ifdef LOG_TO_FILE #define debuglog(fmt, ...) \ dprintf(runtime_log_file_descriptor, "(%d,%lu) %s: " fmt, sched_getcpu(), pthread_self(), __func__, \ ##__VA_ARGS__) #else /* !LOG_TO_FILE */ #define debuglog(fmt, ...) printf("(%d,%lu) %s: " fmt, sched_getcpu(), pthread_self(), __func__, ##__VA_ARGS__) #endif /* LOG_TO_FILE */ #else /* !DEBUG */ #define debuglog(fmt, ...) #endif /* DEBUG */ #define HTTP_MAX_HEADER_COUNT 16 #define HTTP_MAX_HEADER_LENGTH 32 #define HTTP_MAX_HEADER_VALUE_LENGTH 64 #define HTTP_RESPONSE_200_OK "HTTP/1.1 200 OK\r\n" #define HTTP_RESPONSE_CONTENT_LENGTH "Content-length: \r\n\r\n" /* content body follows this */ #define HTTP_RESPONSE_CONTENT_TYPE "Content-type: \r\n" #define HTTP_RESPONSE_CONTENT_TYPE_PLAIN "text/plain" #define JSON_MAX_ELEMENT_COUNT 16 #define JSON_MAX_ELEMENT_SIZE 1024 #define LISTENER_THREAD_CORE_ID 0 /* Dedicated Listener Core */ #define LISTENER_THREAD_MAX_EPOLL_EVENTS 1024 #define MODULE_DEFAULT_REQUEST_RESPONSE_SIZE (PAGE_SIZE) /* Wasm initialization functions generated by the compiler */ #define MODULE_INITIALIZE_GLOBALS "populate_globals" #define MODULE_INITIALIZE_MEMORY "populate_memory" #define MODULE_INITIALIZE_TABLE "populate_table" #define MODULE_INITIALIZE_LIBC "wasmf___init_libc" #define MODULE_MAIN "wasmf_main" #define MODULE_MAX_ARGUMENT_COUNT 16 #define MODULE_MAX_ARGUMENT_SIZE 64 #define MODULE_MAX_MODULE_COUNT 128 #define MODULE_MAX_NAME_LENGTH 32 #define MODULE_MAX_PATH_LENGTH 256 #define MODULE_MAX_PENDING_CLIENT_REQUESTS 1000 #define RUNTIME_LOG_FILE "awesome.log" #define RUNTIME_READ_WRITE_VECTOR_LENGTH 16 #define RUNTIME_MAX_SANDBOX_REQUEST_COUNT (1 << 19) /* random! */ #define SANDBOX_FILE_DESCRIPTOR_PREOPEN_MAGIC (707707707) /* upside down LOLLOLLOL 🤣😂🤣*/ #define SANDBOX_MAX_IO_HANDLE_COUNT 32 #define SOFTWARE_INTERRUPT_TIME_TO_START_IN_USEC (10 * 1000) /* 10 ms */ #define SOFTWARE_INTERRUPT_INTERVAL_DURATION_IN_USEC (5 * 1000) /* 5 ms */ /* If multicore, use all but the dedicated listener core If there are fewer cores than this, main dynamically overrides this and uses all available */ #define WORKER_THREAD_CORE_COUNT (NCORES > 1 ? NCORES - 1 : NCORES)