| 1 | // | 
|---|
| 2 | //  Wasm3, high performance WebAssembly interpreter | 
|---|
| 3 | // | 
|---|
| 4 | //  Copyright © 2019 Steven Massey, Volodymyr Shymanskyy. | 
|---|
| 5 | //  All rights reserved. | 
|---|
| 6 | // | 
|---|
| 7 |  | 
|---|
| 8 | #ifndef wasm3_h | 
|---|
| 9 | #define wasm3_h | 
|---|
| 10 |  | 
|---|
| 11 | #define M3_VERSION_MAJOR 0 | 
|---|
| 12 | #define M3_VERSION_MINOR 5 | 
|---|
| 13 | #define M3_VERSION_REV   0 | 
|---|
| 14 | #define M3_VERSION       "0.5.0" | 
|---|
| 15 |  | 
|---|
| 16 | #include <stdlib.h> | 
|---|
| 17 | #include <stdint.h> | 
|---|
| 18 | #include <inttypes.h> | 
|---|
| 19 | #include <stdarg.h> | 
|---|
| 20 |  | 
|---|
| 21 | #include "wasm3_defs.h" | 
|---|
| 22 |  | 
|---|
| 23 | // Constants | 
|---|
| 24 | #define M3_BACKTRACE_TRUNCATED      (void*)(SIZE_MAX) | 
|---|
| 25 |  | 
|---|
| 26 | #if defined(__cplusplus) | 
|---|
| 27 | extern "C"{ | 
|---|
| 28 | #endif | 
|---|
| 29 |  | 
|---|
| 30 | typedef const char *    M3Result; | 
|---|
| 31 |  | 
|---|
| 32 | struct M3Environment;   typedef struct M3Environment *  IM3Environment; | 
|---|
| 33 | struct M3Runtime;       typedef struct M3Runtime *      IM3Runtime; | 
|---|
| 34 | struct M3Module;        typedef struct M3Module *       IM3Module; | 
|---|
| 35 | struct M3Function;      typedef struct M3Function *     IM3Function; | 
|---|
| 36 | struct M3Global;        typedef struct M3Global *       IM3Global; | 
|---|
| 37 |  | 
|---|
| 38 | typedef struct M3ErrorInfo | 
|---|
| 39 | { | 
|---|
| 40 | M3Result        result; | 
|---|
| 41 |  | 
|---|
| 42 | IM3Runtime      runtime; | 
|---|
| 43 | IM3Module       module; | 
|---|
| 44 | IM3Function     function; | 
|---|
| 45 |  | 
|---|
| 46 | const char *    file; | 
|---|
| 47 | uint32_t        line; | 
|---|
| 48 |  | 
|---|
| 49 | const char *    message; | 
|---|
| 50 | } M3ErrorInfo; | 
|---|
| 51 |  | 
|---|
| 52 | typedef struct M3BacktraceFrame | 
|---|
| 53 | { | 
|---|
| 54 | uint32_t                     moduleOffset; | 
|---|
| 55 | IM3Function                  function; | 
|---|
| 56 |  | 
|---|
| 57 | struct M3BacktraceFrame *    next; | 
|---|
| 58 | } | 
|---|
| 59 | M3BacktraceFrame, * IM3BacktraceFrame; | 
|---|
| 60 |  | 
|---|
| 61 | typedef struct M3BacktraceInfo | 
|---|
| 62 | { | 
|---|
| 63 | IM3BacktraceFrame      frames; | 
|---|
| 64 | IM3BacktraceFrame      lastFrame;    // can be M3_BACKTRACE_TRUNCATED | 
|---|
| 65 | } | 
|---|
| 66 | M3BacktraceInfo, * IM3BacktraceInfo; | 
|---|
| 67 |  | 
|---|
| 68 |  | 
|---|
| 69 | typedef enum M3ValueType | 
|---|
| 70 | { | 
|---|
| 71 | c_m3Type_none   = 0, | 
|---|
| 72 | c_m3Type_i32    = 1, | 
|---|
| 73 | c_m3Type_i64    = 2, | 
|---|
| 74 | c_m3Type_f32    = 3, | 
|---|
| 75 | c_m3Type_f64    = 4, | 
|---|
| 76 |  | 
|---|
| 77 | c_m3Type_unknown | 
|---|
| 78 | } M3ValueType; | 
|---|
| 79 |  | 
|---|
| 80 | typedef struct M3TaggedValue | 
|---|
| 81 | { | 
|---|
| 82 | M3ValueType type; | 
|---|
| 83 | union M3ValueUnion | 
|---|
| 84 | { | 
|---|
| 85 | uint32_t    i32; | 
|---|
| 86 | uint64_t    i64; | 
|---|
| 87 | float       f32; | 
|---|
| 88 | double      f64; | 
|---|
| 89 | } value; | 
|---|
| 90 | } | 
|---|
| 91 | M3TaggedValue, * IM3TaggedValue; | 
|---|
| 92 |  | 
|---|
| 93 | typedef struct M3ImportInfo | 
|---|
| 94 | { | 
|---|
| 95 | const char *    moduleUtf8; | 
|---|
| 96 | const char *    fieldUtf8; | 
|---|
| 97 | } | 
|---|
| 98 | M3ImportInfo, * IM3ImportInfo; | 
|---|
| 99 |  | 
|---|
| 100 |  | 
|---|
| 101 | typedef struct M3ImportContext | 
|---|
| 102 | { | 
|---|
| 103 | void *          userdata; | 
|---|
| 104 | IM3Function     function; | 
|---|
| 105 | } | 
|---|
| 106 | M3ImportContext, * IM3ImportContext; | 
|---|
| 107 |  | 
|---|
| 108 | // ------------------------------------------------------------------------------------------------------------------------------- | 
|---|
| 109 | //  error codes | 
|---|
| 110 | // ------------------------------------------------------------------------------------------------------------------------------- | 
|---|
| 111 |  | 
|---|
| 112 | # if defined(M3_IMPLEMENT_ERROR_STRINGS) | 
|---|
| 113 | #   define d_m3ErrorConst(LABEL, STRING)        extern const M3Result m3Err_##LABEL = { STRING }; | 
|---|
| 114 | # else | 
|---|
| 115 | #   define d_m3ErrorConst(LABEL, STRING)        extern const M3Result m3Err_##LABEL; | 
|---|
| 116 | # endif | 
|---|
| 117 |  | 
|---|
| 118 | // ------------------------------------------------------------------------------------------------------------------------------- | 
|---|
| 119 |  | 
|---|
| 120 | d_m3ErrorConst  (none,                          NULL) | 
|---|
| 121 |  | 
|---|
| 122 | // general errors | 
|---|
| 123 | d_m3ErrorConst  (mallocFailed, "memory allocation failed") | 
|---|
| 124 |  | 
|---|
| 125 | // parse errors | 
|---|
| 126 | d_m3ErrorConst  (incompatibleWasmVersion, "incompatible Wasm binary version") | 
|---|
| 127 | d_m3ErrorConst  (wasmMalformed, "malformed Wasm binary") | 
|---|
| 128 | d_m3ErrorConst  (misorderedWasmSection, "out of order Wasm section") | 
|---|
| 129 | d_m3ErrorConst  (wasmUnderrun, "underrun while parsing Wasm binary") | 
|---|
| 130 | d_m3ErrorConst  (wasmOverrun, "overrun while parsing Wasm binary") | 
|---|
| 131 | d_m3ErrorConst  (wasmMissingInitExpr, "missing init_expr in Wasm binary") | 
|---|
| 132 | d_m3ErrorConst  (lebOverflow, "LEB encoded value overflow") | 
|---|
| 133 | d_m3ErrorConst  (missingUTF8, "invalid length UTF-8 string") | 
|---|
| 134 | d_m3ErrorConst  (wasmSectionUnderrun, "section underrun while parsing Wasm binary") | 
|---|
| 135 | d_m3ErrorConst  (wasmSectionOverrun, "section overrun while parsing Wasm binary") | 
|---|
| 136 | d_m3ErrorConst  (invalidTypeId, "unknown value_type") | 
|---|
| 137 | d_m3ErrorConst  (tooManyMemorySections, "only one memory per module is supported") | 
|---|
| 138 | d_m3ErrorConst  (tooManyArgsRets, "too many arguments or return values") | 
|---|
| 139 |  | 
|---|
| 140 | // link errors | 
|---|
| 141 | d_m3ErrorConst  (moduleNotLinked, "attempting to use module that is not loaded") | 
|---|
| 142 | d_m3ErrorConst  (moduleAlreadyLinked, "attempting to bind module to multiple runtimes") | 
|---|
| 143 | d_m3ErrorConst  (functionLookupFailed, "function lookup failed") | 
|---|
| 144 | d_m3ErrorConst  (functionImportMissing, "missing imported function") | 
|---|
| 145 |  | 
|---|
| 146 | d_m3ErrorConst  (malformedFunctionSignature, "malformed function signature") | 
|---|
| 147 |  | 
|---|
| 148 | // compilation errors | 
|---|
| 149 | d_m3ErrorConst  (noCompiler, "no compiler found for opcode") | 
|---|
| 150 | d_m3ErrorConst  (unknownOpcode, "unknown opcode") | 
|---|
| 151 | d_m3ErrorConst  (restrictedOpcode, "restricted opcode") | 
|---|
| 152 | d_m3ErrorConst  (functionStackOverflow, "compiling function overran its stack height limit") | 
|---|
| 153 | d_m3ErrorConst  (functionStackUnderrun, "compiling function underran the stack") | 
|---|
| 154 | d_m3ErrorConst  (mallocFailedCodePage, "memory allocation failed when acquiring a new M3 code page") | 
|---|
| 155 | d_m3ErrorConst  (settingImmutableGlobal, "attempting to set an immutable global") | 
|---|
| 156 | d_m3ErrorConst  (typeMismatch, "incorrect type on stack") | 
|---|
| 157 | d_m3ErrorConst  (typeCountMismatch, "incorrect value count on stack") | 
|---|
| 158 |  | 
|---|
| 159 | // runtime errors | 
|---|
| 160 | d_m3ErrorConst  (missingCompiledCode, "function is missing compiled m3 code") | 
|---|
| 161 | d_m3ErrorConst  (wasmMemoryOverflow, "runtime ran out of memory") | 
|---|
| 162 | d_m3ErrorConst  (globalMemoryNotAllocated, "global memory is missing from a module") | 
|---|
| 163 | d_m3ErrorConst  (globaIndexOutOfBounds, "global index is too large") | 
|---|
| 164 | d_m3ErrorConst  (argumentCountMismatch, "argument count mismatch") | 
|---|
| 165 | d_m3ErrorConst  (argumentTypeMismatch, "argument type mismatch") | 
|---|
| 166 | d_m3ErrorConst  (globalLookupFailed, "global lookup failed") | 
|---|
| 167 | d_m3ErrorConst  (globalTypeMismatch, "global type mismatch") | 
|---|
| 168 | d_m3ErrorConst  (globalNotMutable, "global is not mutable") | 
|---|
| 169 |  | 
|---|
| 170 | // traps | 
|---|
| 171 | d_m3ErrorConst  (trapOutOfBoundsMemoryAccess, "[trap] out of bounds memory access") | 
|---|
| 172 | d_m3ErrorConst  (trapDivisionByZero, "[trap] integer divide by zero") | 
|---|
| 173 | d_m3ErrorConst  (trapIntegerOverflow, "[trap] integer overflow") | 
|---|
| 174 | d_m3ErrorConst  (trapIntegerConversion, "[trap] invalid conversion to integer") | 
|---|
| 175 | d_m3ErrorConst  (trapIndirectCallTypeMismatch, "[trap] indirect call type mismatch") | 
|---|
| 176 | d_m3ErrorConst  (trapTableIndexOutOfRange, "[trap] undefined element") | 
|---|
| 177 | d_m3ErrorConst  (trapTableElementIsNull, "[trap] null table element") | 
|---|
| 178 | d_m3ErrorConst  (trapExit, "[trap] program called exit") | 
|---|
| 179 | d_m3ErrorConst  (trapAbort, "[trap] program called abort") | 
|---|
| 180 | d_m3ErrorConst  (trapUnreachable, "[trap] unreachable executed") | 
|---|
| 181 | d_m3ErrorConst  (trapStackOverflow, "[trap] stack overflow") | 
|---|
| 182 |  | 
|---|
| 183 |  | 
|---|
| 184 | //------------------------------------------------------------------------------------------------------------------------------- | 
|---|
| 185 | //  configuration, can be found in m3_config.h, m3_config_platforms.h, m3_core.h) | 
|---|
| 186 | //------------------------------------------------------------------------------------------------------------------------------- | 
|---|
| 187 |  | 
|---|
| 188 | //------------------------------------------------------------------------------------------------------------------------------- | 
|---|
| 189 | //  global environment than can host multiple runtimes | 
|---|
| 190 | //------------------------------------------------------------------------------------------------------------------------------- | 
|---|
| 191 | IM3Environment      m3_NewEnvironment           (void); | 
|---|
| 192 |  | 
|---|
| 193 | void                m3_FreeEnvironment          (IM3Environment i_environment); | 
|---|
| 194 |  | 
|---|
| 195 | typedef M3Result (* M3SectionHandler) (IM3Module i_module, const char* name, const uint8_t * start, const uint8_t * end); | 
|---|
| 196 |  | 
|---|
| 197 | void                m3_SetCustomSectionHandler  (IM3Environment i_environment,    M3SectionHandler i_handler); | 
|---|
| 198 |  | 
|---|
| 199 |  | 
|---|
| 200 | //------------------------------------------------------------------------------------------------------------------------------- | 
|---|
| 201 | //  execution context | 
|---|
| 202 | //------------------------------------------------------------------------------------------------------------------------------- | 
|---|
| 203 |  | 
|---|
| 204 | IM3Runtime          m3_NewRuntime               (IM3Environment         io_environment, | 
|---|
| 205 | uint32_t               i_stackSizeInBytes, | 
|---|
| 206 | void *                 i_userdata); | 
|---|
| 207 |  | 
|---|
| 208 | void                m3_FreeRuntime              (IM3Runtime             i_runtime); | 
|---|
| 209 |  | 
|---|
| 210 | // Wasm currently only supports one memory region. i_memoryIndex should be zero. | 
|---|
| 211 | uint8_t *           m3_GetMemory                (IM3Runtime             i_runtime, | 
|---|
| 212 | uint32_t *             o_memorySizeInBytes, | 
|---|
| 213 | uint32_t               i_memoryIndex); | 
|---|
| 214 |  | 
|---|
| 215 | // This is used internally by Raw Function helpers | 
|---|
| 216 | uint32_t            m3_GetMemorySize            (IM3Runtime             i_runtime); | 
|---|
| 217 |  | 
|---|
| 218 | void *              m3_GetUserData              (IM3Runtime             i_runtime); | 
|---|
| 219 |  | 
|---|
| 220 |  | 
|---|
| 221 | //------------------------------------------------------------------------------------------------------------------------------- | 
|---|
| 222 | //  modules | 
|---|
| 223 | //------------------------------------------------------------------------------------------------------------------------------- | 
|---|
| 224 |  | 
|---|
| 225 | // i_wasmBytes data must be persistent during the lifetime of the module | 
|---|
| 226 | M3Result            m3_ParseModule              (IM3Environment         i_environment, | 
|---|
| 227 | IM3Module *            o_module, | 
|---|
| 228 | const uint8_t * const  i_wasmBytes, | 
|---|
| 229 | uint32_t               i_numWasmBytes); | 
|---|
| 230 |  | 
|---|
| 231 | // Only modules not loaded into a M3Runtime need to be freed. A module is considered unloaded if | 
|---|
| 232 | // a. m3_LoadModule has not yet been called on that module. Or, | 
|---|
| 233 | // b. m3_LoadModule returned a result. | 
|---|
| 234 | void                m3_FreeModule               (IM3Module i_module); | 
|---|
| 235 |  | 
|---|
| 236 | //  LoadModule transfers ownership of a module to the runtime. Do not free modules once successfully loaded into the runtime | 
|---|
| 237 | M3Result            m3_LoadModule               (IM3Runtime io_runtime,  IM3Module io_module); | 
|---|
| 238 |  | 
|---|
| 239 | // Optional, compiles all functions in the module | 
|---|
| 240 | M3Result            m3_CompileModule            (IM3Module io_module); | 
|---|
| 241 |  | 
|---|
| 242 | // Calling m3_RunStart is optional | 
|---|
| 243 | M3Result            m3_RunStart                 (IM3Module i_module); | 
|---|
| 244 |  | 
|---|
| 245 | // Arguments and return values are passed in and out through the stack pointer _sp. | 
|---|
| 246 | // Placeholder return value slots are first and arguments after. So, the first argument is at _sp [numReturns] | 
|---|
| 247 | // Return values should be written into _sp [0] to _sp [num_returns - 1] | 
|---|
| 248 | typedef const void * (* M3RawCall) (IM3Runtime runtime, IM3ImportContext _ctx, uint64_t * _sp, void * _mem); | 
|---|
| 249 |  | 
|---|
| 250 | M3Result            m3_LinkRawFunction          (IM3Module              io_module, | 
|---|
| 251 | const char * const     i_moduleName, | 
|---|
| 252 | const char * const     i_functionName, | 
|---|
| 253 | const char * const     i_signature, | 
|---|
| 254 | M3RawCall              i_function); | 
|---|
| 255 |  | 
|---|
| 256 | M3Result            m3_LinkRawFunctionEx        (IM3Module              io_module, | 
|---|
| 257 | const char * const     i_moduleName, | 
|---|
| 258 | const char * const     i_functionName, | 
|---|
| 259 | const char * const     i_signature, | 
|---|
| 260 | M3RawCall              i_function, | 
|---|
| 261 | const void *           i_userdata); | 
|---|
| 262 |  | 
|---|
| 263 | const char*         m3_GetModuleName            (IM3Module i_module); | 
|---|
| 264 | void                m3_SetModuleName            (IM3Module i_module, const char* name); | 
|---|
| 265 | IM3Runtime          m3_GetModuleRuntime         (IM3Module i_module); | 
|---|
| 266 |  | 
|---|
| 267 | //------------------------------------------------------------------------------------------------------------------------------- | 
|---|
| 268 | //  globals | 
|---|
| 269 | //------------------------------------------------------------------------------------------------------------------------------- | 
|---|
| 270 | IM3Global           m3_FindGlobal               (IM3Module              io_module, | 
|---|
| 271 | const char * const     i_globalName); | 
|---|
| 272 |  | 
|---|
| 273 | M3Result            m3_GetGlobal                (IM3Global              i_global, | 
|---|
| 274 | IM3TaggedValue         o_value); | 
|---|
| 275 |  | 
|---|
| 276 | M3Result            m3_SetGlobal                (IM3Global              i_global, | 
|---|
| 277 | const IM3TaggedValue   i_value); | 
|---|
| 278 |  | 
|---|
| 279 | M3ValueType         m3_GetGlobalType            (IM3Global              i_global); | 
|---|
| 280 |  | 
|---|
| 281 | //------------------------------------------------------------------------------------------------------------------------------- | 
|---|
| 282 | //  functions | 
|---|
| 283 | //------------------------------------------------------------------------------------------------------------------------------- | 
|---|
| 284 | M3Result            m3_Yield                    (void); | 
|---|
| 285 |  | 
|---|
| 286 | // o_function is valid during the lifetime of the originating runtime | 
|---|
| 287 | M3Result            m3_FindFunction             (IM3Function *          o_function, | 
|---|
| 288 | IM3Runtime             i_runtime, | 
|---|
| 289 | const char * const     i_functionName); | 
|---|
| 290 |  | 
|---|
| 291 | uint32_t            m3_GetArgCount              (IM3Function i_function); | 
|---|
| 292 | uint32_t            m3_GetRetCount              (IM3Function i_function); | 
|---|
| 293 | M3ValueType         m3_GetArgType               (IM3Function i_function, uint32_t i_index); | 
|---|
| 294 | M3ValueType         m3_GetRetType               (IM3Function i_function, uint32_t i_index); | 
|---|
| 295 |  | 
|---|
| 296 | M3Result            m3_CallV                    (IM3Function i_function, ...); | 
|---|
| 297 | M3Result            m3_CallVL                   (IM3Function i_function, va_list i_args); | 
|---|
| 298 | M3Result            m3_Call                     (IM3Function i_function, uint32_t i_argc, const void * i_argptrs[]); | 
|---|
| 299 | M3Result            m3_CallArgv                 (IM3Function i_function, uint32_t i_argc, const char * i_argv[]); | 
|---|
| 300 |  | 
|---|
| 301 | M3Result            m3_GetResultsV              (IM3Function i_function, ...); | 
|---|
| 302 | M3Result            m3_GetResultsVL             (IM3Function i_function, va_list o_rets); | 
|---|
| 303 | M3Result            m3_GetResults               (IM3Function i_function, uint32_t i_retc, const void * o_retptrs[]); | 
|---|
| 304 |  | 
|---|
| 305 |  | 
|---|
| 306 | void                m3_GetErrorInfo             (IM3Runtime i_runtime, M3ErrorInfo* o_info); | 
|---|
| 307 | void                m3_ResetErrorInfo           (IM3Runtime i_runtime); | 
|---|
| 308 |  | 
|---|
| 309 | const char*         m3_GetFunctionName          (IM3Function i_function); | 
|---|
| 310 | IM3Module           m3_GetFunctionModule        (IM3Function i_function); | 
|---|
| 311 |  | 
|---|
| 312 | //------------------------------------------------------------------------------------------------------------------------------- | 
|---|
| 313 | //  debug info | 
|---|
| 314 | //------------------------------------------------------------------------------------------------------------------------------- | 
|---|
| 315 |  | 
|---|
| 316 | void                m3_PrintRuntimeInfo         (IM3Runtime i_runtime); | 
|---|
| 317 | void                m3_PrintM3Info              (void); | 
|---|
| 318 | void                m3_PrintProfilerInfo        (void); | 
|---|
| 319 |  | 
|---|
| 320 | // The runtime owns the backtrace, do not free the backtrace you obtain. Returns NULL if there's no backtrace. | 
|---|
| 321 | IM3BacktraceInfo    m3_GetBacktrace             (IM3Runtime i_runtime); | 
|---|
| 322 |  | 
|---|
| 323 | //------------------------------------------------------------------------------------------------------------------------------- | 
|---|
| 324 | //  raw function definition helpers | 
|---|
| 325 | //------------------------------------------------------------------------------------------------------------------------------- | 
|---|
| 326 |  | 
|---|
| 327 | # define m3ApiOffsetToPtr(offset)   (void*)((uint8_t*)_mem + (uint32_t)(offset)) | 
|---|
| 328 | # define m3ApiPtrToOffset(ptr)      (uint32_t)((uint8_t*)ptr - (uint8_t*)_mem) | 
|---|
| 329 |  | 
|---|
| 330 | # define m3ApiReturnType(TYPE)      TYPE* raw_return = ((TYPE*) (_sp++)); | 
|---|
| 331 | # define m3ApiGetArg(TYPE, NAME)    TYPE NAME = * ((TYPE *) (_sp++)); | 
|---|
| 332 | # define m3ApiGetArgMem(TYPE, NAME) TYPE NAME = (TYPE)m3ApiOffsetToPtr(* ((uint32_t *) (_sp++))); | 
|---|
| 333 |  | 
|---|
| 334 | # define m3ApiIsNullPtr(addr)       ((void*)(addr) <= _mem) | 
|---|
| 335 | # define m3ApiCheckMem(addr, len)   { if (M3_UNLIKELY(((void*)(addr) < _mem) || ((uint64_t)(uintptr_t)(addr) + (len)) > ((uint64_t)(uintptr_t)(_mem)+m3_GetMemorySize(runtime)))) m3ApiTrap(m3Err_trapOutOfBoundsMemoryAccess); } | 
|---|
| 336 |  | 
|---|
| 337 | # define m3ApiRawFunction(NAME)     const void * NAME (IM3Runtime runtime, IM3ImportContext _ctx, uint64_t * _sp, void * _mem) | 
|---|
| 338 | # define m3ApiReturn(VALUE)         { *raw_return = (VALUE); return m3Err_none; } | 
|---|
| 339 | # define m3ApiTrap(VALUE)           { return VALUE; } | 
|---|
| 340 | # define m3ApiSuccess()             { return m3Err_none; } | 
|---|
| 341 |  | 
|---|
| 342 | # if defined(M3_BIG_ENDIAN) | 
|---|
| 343 | #  define m3ApiReadMem8(ptr)         (* (uint8_t *)(ptr)) | 
|---|
| 344 | #  define m3ApiReadMem16(ptr)        m3_bswap16((* (uint16_t *)(ptr))) | 
|---|
| 345 | #  define m3ApiReadMem32(ptr)        m3_bswap32((* (uint32_t *)(ptr))) | 
|---|
| 346 | #  define m3ApiReadMem64(ptr)        m3_bswap64((* (uint64_t *)(ptr))) | 
|---|
| 347 | #  define m3ApiWriteMem8(ptr, val)   { * (uint8_t  *)(ptr)  = (val); } | 
|---|
| 348 | #  define m3ApiWriteMem16(ptr, val)  { * (uint16_t *)(ptr) = m3_bswap16((val)); } | 
|---|
| 349 | #  define m3ApiWriteMem32(ptr, val)  { * (uint32_t *)(ptr) = m3_bswap32((val)); } | 
|---|
| 350 | #  define m3ApiWriteMem64(ptr, val)  { * (uint64_t *)(ptr) = m3_bswap64((val)); } | 
|---|
| 351 | # else | 
|---|
| 352 | #  define m3ApiReadMem8(ptr)         (* (uint8_t *)(ptr)) | 
|---|
| 353 | #  define m3ApiReadMem16(ptr)        (* (uint16_t *)(ptr)) | 
|---|
| 354 | #  define m3ApiReadMem32(ptr)        (* (uint32_t *)(ptr)) | 
|---|
| 355 | #  define m3ApiReadMem64(ptr)        (* (uint64_t *)(ptr)) | 
|---|
| 356 | #  define m3ApiWriteMem8(ptr, val)   { * (uint8_t  *)(ptr) = (val); } | 
|---|
| 357 | #  define m3ApiWriteMem16(ptr, val)  { * (uint16_t *)(ptr) = (val); } | 
|---|
| 358 | #  define m3ApiWriteMem32(ptr, val)  { * (uint32_t *)(ptr) = (val); } | 
|---|
| 359 | #  define m3ApiWriteMem64(ptr, val)  { * (uint64_t *)(ptr) = (val); } | 
|---|
| 360 | # endif | 
|---|
| 361 |  | 
|---|
| 362 | #if defined(__cplusplus) | 
|---|
| 363 | } | 
|---|
| 364 | #endif | 
|---|
| 365 |  | 
|---|
| 366 | #endif // wasm3_h | 
|---|
| 367 |  | 
|---|