-
Notifications
You must be signed in to change notification settings - Fork 15
External API
The inNative External API is what applications call to assemble an environment and compile WebAssembly modules. The functions covered here are acquired using a call to innative_runtime
, which resolves all the function pointers in an INExports
struct, either statically or dynamically. This ensures that switching between embedded and dynamic runtimes does not require any code changes. In addition to these functions, there is also the Metadata API and the Schema Manipulation API. The second part of this page covers the data structures used in the API functions.
Environment* CreateEnvironment(unsigned int modules, unsigned int maxthreads, const char* arg0);
- modules: The number of modules that are expected to be added to the environment - can just be an estimate.
- maxthreads: The maximum number of threads to use for multithreading. 0 defaults to logical cores.
- arg0: The first argument sent to the program. Used to determine binary location on POSIX systems.
-
Returns a pointer to a new
Environment
structure, which must be destroyed usingDestroyEnvironment()
. Creates an environment initialized to default values, which must be destroyed usingDestroyEnvironment()
.
void AddModule(Environment* env, const void* data, uint64_t size, const char* name, int* err);
- env: The environment to modify.
- data: Either a pointer to the module in memory, or a UTF8 encoded null-terminated string pointing to a file that contains the module.
- size: The length of the memory that the data pointer points to, or zero if the data pointer is actually a UTF8 encoded null terminated string.
- name: A name to use for the module. If the module data does not contain a name, this will be used.
- err: A pointer to an integer that receives an error code should the function fail. Not valid until FinalizeEnvironment() is called.
- Returns Nothing
Adds a module to an environment. This could happen asynchronously if multithreading is enabled, in which case err
won't be valid until FinalizeEnvironment()
is called to resolve all pending module loads.
int AddModuleObject(Environment* env, const Module* m);
- env The environment to modify.
- m The module to add to the environment. This must be a valid Module object or the validation step will fail. The module will be copied into the environment - further modifications to the given module pointer won't affect the environment's internal copy.
- Returns a standard IN_ERROR code, or ERR_SUCCESS if it succeeds.
Adds a prebuilt module object to the environment. This happens synchronously, regardless of multithreading flags.
void AddWhitelist (Environment* env, const char* module_name, const char* export_name);
- env: The environment to modify.
- module_name: The name of a module, in case the C function is actually a name-mangled webassembly function. This parameter should be null for standard C functions.
- export_name: The name of the function to add to the whitelist. Must be a valid UTF8 webassembly function name.
- Returns nothing
Adds a whitelist entry to the environment. This will only be used if the whitelist is enabled via the ENV_WHITELIST flag.
enum IN_ERROR AddEmbedding(Environment* env, int tag, const void* data, uint64_t size);
- env: The environment to modify.
- tag: An IN_EMBEDDING_TAGS enumeration option that provides an optional hint for the type of file. To automatically choose, set to 0 (equivalent to IN_TAG_ANY).
- data: Either a pointer to memory, or a UTF8 encoded null-terminated string pointing to a file.
- size: The length of the memory that the data pointer points to. If size is 0, the data pointer is actually a null terminated UTF8 encoded file path.
- Returns a standard IN_ERROR code, or ERR_SUCCESS if it succeeds.
Adds an embedding to the environment. This is usually a static or shared C library that exposes C functions that the webassembly modules can call.
enum IN_ERROR AddCustomExport(Environment* env, const char* symbol);
- env: The environment to modify.
- symbol: The null-terminated name of the symbol to export.
- Returns a standard IN_ERROR code, or ERR_SUCCESS if it succeeds.
Tells the linker to export the given symbol from the resulting binary.
enum IN_ERROR FinalizeEnvironment(Environment* env);
- env: The environment to finalize
- Returns a standard IN_ERROR code, or ERR_SUCCESS if it succeeds. Finalizes the environment, blocking until all modules have finished loading (in case of any asynchronous loads) and ensures all configuration data is loaded.
enum IN_ERROR Validate(Environment* env);
- env: The environment to verify.
- Returns a standard IN_ERROR code, or ERR_SUCCESS if it succeeds.
Validates all the modules in the environment using the current configuration.
enum IN_ERROR Compile(Environment* env, const char* file);
- env: The environment to compile.
- file: The path of the output file that is produced.
- Returns a standard IN_ERROR code, or ERR_SUCCESS if it succeeds.
Compiles all the modules in the environment using the current configuration and any cached results into a binary file.
void* LoadAssembly(const char* file);
- file: the path of the file to load.
-
Returns a pointer to the loaded assembly that must be freed using
FreeAssembly()
, orNULL
if the load fails.
Loads a webassembly binary (usually a dynamic library) produced by Compile into memory, allowing you to load functions and other exported symbols.
void FreeAssembly (void* assembly);
-
assembly: A pointer to a webassembly binary loaded by
LoadAssembly()
. - Returns nothing.
Frees a webassembly binary, unloading it from memory and performing any cleanup required.
void ClearEnvironmentCache(Environment* env, Module* m);
- env: The environment to clear.
- m: An optional module whose compilation cache will be cleared. If this is a null pointer, instead clears the entire cache of the environment.
- Returns nothing.
Clears the environment's cached compilation of a given module, or clears the entire cache if the module is a null pointer.
const char* GetTypeEncodingString(int type_encoding);
-
error_code: The
TYPE_ENCODING
value to get the string representation of. -
Returns a string representation of the type encoding, or
NULL
if it fails.
Returns the string representation of a TYPE_ENCODING
enumeration, or NULL
if the lookup fails. Useful for debuggers.
const char* GetErrorString(int error_code);
-
error_code: The
IN_ERROR
code to get the string representation of. -
Returns a string representation of the error code, or
NULL
if it fails.
Returns the string representation of an IN_ERROR
enumeration, or NULL
if the lookup fails. Useful for debuggers.
void DestroyEnvironment(Environment* env);
- env: The environment to destroy.
- Returns nothing.
Destroys an environment and safely deconstructs all it's caches and memory allocations.
int CompileScript(const uint8_t* data, size_t sz, Environment* env, bool always_compile, const char* output);
- data: Either a pointer to the script in memory, or a UTF8 encoded null-terminated string pointing to a file that contains the script.
- sz: The length of the memory that the data pointer points to, or zero if the data pointer is actually a UTF8 encoded null terminated string.
- env: The environment to execute the script with. This environment can potentially be modified by the script being executed.
- always_compile: By default, this function only performs a compilation when necessary to call a function. If this is set to true, all modules are compiled even if no function inside them is called.
-
output: Sets the output directory where compilation results should be stored. Intermediate results will still be in
env->objpath
-
Returns an IN_ERROR error code as an integer, or
ERR_SUCCESS
(0) if it succeeds.
Compiles and executes a .wast script using the given environment. This execution will modify the environment and add all modules referenced in the script according to the registration rules.
These functions are not part of the official External API, but can be accessed when statically linking or embedding the runtime. They are mostly used by inNative tools for specialized operations that most normal programs don't need to worry about.
IN_COMPILER_DLLEXPORT extern void innative_set_work_dir_to_bin(const char* arg0);
- arg:0 the first argument sent to the program. Used to determine binary location on POSIX systems.
- Returns nothing
Convenience function that sets the working directory to the executable's root directory.
IN_COMPILER_DLLEXPORT extern int innative_install(const char* arg0, bool full);
- arg:0 the first argument sent to the program. Used to determine binary location on POSIX systems.
- full: On windows, performs a "full" installation, which associates the runtime with .wat/.wast/.wasm files.
- Returns an IN_ERROR error code as an integer, or ERR_SUCCESS (0) if it succeeds.
Installs this runtime, usually only called by innative-cmd, which makes assumptions about file locations.
IN_COMPILER_DLLEXPORT extern int innative_uninstall();
- Returns an IN_ERROR error code as an integer, or ERR_SUCCESS (0) if it succeeds.
Uninstalls whatever runtime version this is from the operating system.
IN_COMPILER_DLLEXPORT extern int innative_compile_llvm(const char** files, size_t n, int flags, const char* out, FILE* log);
- files: An array of UTF8 file paths to compile.
- n: The length of the 'files' array.
- flags: Environment flags to compile with. This is mostly used to set the ENV_LIBRARY flag in case this should be a shared library.
- out: The output file that will store the compilation result.
- log: A C FILE* stream that should be used for logging errors or warnings.
- Returns an IN_ERROR error code as an integer, or ERR_SUCCESS (0) if it succeeds.
Performs a reverse compilation of LLVM IR into WebAssembly using the built-in LLVM version in this runtime.
This is a list of the external data structures used by the API, with instructions on how they work.
typedef struct __WASM_ENVIRONMENT
{
size_t n_modules;
size_t size;
size_t capacity;
Module* modules;
Embedding* embeddings;
ValidationError* errors;
uint64_t flags;
uint64_t features;
uint64_t optimize;
unsigned int maxthreads;
const char* libpath;
const char* objpath;
const char* linker;
const char* system;
struct __WASM_ALLOCATOR* alloc;
int loglevel;
FILE* log;
void(*wasthook)(void*);
struct kh_modules_s* modulemap;
struct kh_modulepair_s* whitelist;
struct kh_cimport_s* cimports;
__LLVM_CONTEXT* context;
} Environment;
The Environment
struct represents the compiler's current state, and holds all current modules, embeddings, flags, and any other configuration data. When compiling a binary, this holds all relevent information the compiler needs (except the output file path). Below, we describe the public fields of the Environment struct. Any fields not covered here are internal and should not be touched by other programs.
This represents the number of fully loaded modules, which is seperate from the total number of modules. This is simply a count used by FinalizeEnvironment()
to figure out when all asyncronous loads have finished. Should be treated as read-only, but could be used to feed a progress bar if accessed using atomic loads.
Total number of modules that are currently loading or have been loaded. This is the real number of modules that have been added to the Environment. Once size
is equal to n_modules
, they have all been loaded. Should be treated as read-only, can be used to tell the maximum possible value of n_modules
for a progress bar.
Internal capacity of the modules array. Do not use.
Pointer to the modules array. This is safe to read and modify after FinalizeEnvironment()
has been called. Both n_modules
and size
can be used to retrieve the array length, but n_modules
is preferred.
This is a singly linked list of embedding environments. It should be treated as read-only, but it can be walked by the host. Use AddEmbedding
to correctly append embeddings to this list.
This is a singly linked list of either validation errors or certain compiler errors. It should be considered read-only, but it is always safe to iterate through, even asyncronously during compilation (errors are added on the end using a lockless, thread-safe algorithm).
Stores standard flags from the WASM_ENVIRONMENT_FLAGS enumeration.
Stores feature flags from the WASM_FEATURE_FLAGS enumeration.
Stores optimization flags from the WASM_OPTIMIZE enumeration.
Stores the maximum number of threads to use for multithreaded compilation. Set when creating the environment and shouldn't be changed afterwards.
This is the directory used to find library files, including the Default Environment. Defaults to the EXE's current directory, and can be changed at any time, but changing it may invalidate cached compilation results. On Linux, /usr/lib/
is always searched in addition to this directory.
Directory used to store intermediate compilation results, like .o
files. These are only destroyed once the Environment is destroyed, so if you are compiling multiple things, the Environment can re-use cached compilation results when appropriate. Defaults to NULL
, and if it is still set to NULL
when compilation starts, will be set to the output file's directory. In order to preserve intermediate results, it will stay set to the first output file's directory. If you are compiling more than one thing, it is highly recommended you actually set this to a suitable directory before starting. It can be changed at any time, except during compilation, but doing so will cause inNative to lose track of any existing intermediate results and fail to delete them.
Species an alternative linker, usually the system linker. This linker must use the operating system's standard linker interface, or it simply won't work. Intended as a fallback in case a bug in LLD
prevents it from linking correctly. Can be changed at any time, but may invalidate cached compilation results.
Determines the module that is considered the "system level" module from which to import C functions. This module is basically aliased to a blank module name for the purposes of Name Mangling. Can be changed at any point, but may invalidate or break compilation completely if done during or in-between compilation.
Determines the log level, which should be set to a value from WASM_LOG_LEVEL
. Only messages with priority equal to or greater than the given level will be logged. Defaults to LOG_WARNING, which logs all warnings, errors, and fatal errors. Setting it to LOG_NOTICE
will log all notices, warnings, errors, and fatal errors, which is useful for debugging WebAssembly modules. LOG_DEBUG
is generally for debugging inNative itself
Determines the output stream used for logging purposes. Can be changed in-between operations, but usually should be set after environment creation and never touched afterwards.
This is a hook function that fires whenever the .wast
parser performs a compilation. Used primarily for progress bars or debugging purposes.