// // m3_core.h // // Created by Steven Massey on 4/15/19. // Copyright © 2019 Steven Massey. All rights reserved. // #ifndef m3_core_h #define m3_core_h #include #include #include #include #include #include "wasm3.h" #include "m3_config.h" # if defined(__cplusplus) # define d_m3BeginExternC extern "C" { # define d_m3EndExternC } # else # define d_m3BeginExternC # define d_m3EndExternC # endif d_m3BeginExternC #if !defined(d_m3ShortTypesDefined) #if d_m3HasFloat || d_m3NoFloatDynamic typedef double f64; typedef float f32; #endif typedef uint64_t u64; typedef int64_t i64; typedef uint32_t u32; typedef int32_t i32; typedef uint16_t u16; typedef int16_t i16; typedef uint8_t u8; typedef int8_t i8; #endif // d_m3ShortTypesDefined #define PRIf32 "f" #define PRIf64 "lf" typedef const void * m3ret_t; typedef const void * voidptr_t; typedef const char * cstr_t; typedef const char * const ccstr_t; typedef const u8 * bytes_t; typedef const u8 * const cbytes_t; typedef u16 m3opcode_t; typedef i64 m3reg_t; # if d_m3Use32BitSlots typedef u32 m3slot_t; # else typedef u64 m3slot_t; # endif typedef m3slot_t * m3stack_t; typedef const void * const cvptr_t; # if defined (DEBUG) # define d_m3Log(CATEGORY, FMT, ...) printf (" %8s | " FMT, #CATEGORY, ##__VA_ARGS__); # if d_m3LogParse # define m3log_parse(CATEGORY, FMT, ...) d_m3Log(CATEGORY, FMT, ##__VA_ARGS__) # else # define m3log_parse(...) {} # endif # if d_m3LogCompile # define m3log_compile(CATEGORY, FMT, ...) d_m3Log(CATEGORY, FMT, ##__VA_ARGS__) # else # define m3log_compile(...) {} # endif # if d_m3LogWasmStack # define m3log_stack(CATEGORY, FMT, ...) d_m3Log(CATEGORY, FMT, ##__VA_ARGS__) # else # define m3log_stack(...) {} # endif # if d_m3LogEmit # define m3log_emit(CATEGORY, FMT, ...) d_m3Log(CATEGORY, FMT, ##__VA_ARGS__) # else # define m3log_emit(...) {} # endif # if d_m3LogCodePages # define m3log_code(CATEGORY, FMT, ...) d_m3Log(CATEGORY, FMT, ##__VA_ARGS__) # else # define m3log_code(...) {} # endif # if d_m3LogModule # define m3log_module(CATEGORY, FMT, ...) d_m3Log(CATEGORY, FMT, ##__VA_ARGS__) # else # define m3log_module(...) {} # endif # if d_m3LogRuntime # define m3log_runtime(CATEGORY, FMT, ...) d_m3Log(CATEGORY, FMT, ##__VA_ARGS__) # else # define m3log_runtime(...) {} # endif # if d_m3LogExec # define m3log_exec(CATEGORY, FMT, ...) d_m3Log(CATEGORY, FMT, ##__VA_ARGS__) # else # define m3log_exec(...) {} # endif # define m3log(CATEGORY, FMT, ...) m3log_##CATEGORY (CATEGORY, FMT "\n", ##__VA_ARGS__) # else # define d_m3Log(CATEGORY, FMT, ...) {} # define m3log(CATEGORY, FMT, ...) {} # endif # if (defined(DEBUG) || defined(ASSERTS)) && !defined(NASSERTS) # define d_m3Assert(ASS) assert (ASS) # else # define d_m3Assert(ASS) # endif typedef void /*const*/ * code_t; typedef code_t const * /*__restrict__*/ pc_t; typedef struct M3MemoryHeader { IM3Runtime runtime; void * maxStack; size_t length; } M3MemoryHeader; struct M3CodeMappingPage; typedef struct M3CodePageHeader { struct M3CodePage * next; u32 lineIndex; u32 numLines; u32 sequence; // this is just used for debugging; could be removed u32 usageCount; # if d_m3RecordBacktraces struct M3CodeMappingPage * mapping; # endif // d_m3RecordBacktraces } M3CodePageHeader; #define d_m3CodePageFreeLinesThreshold 4+2 // max is: select _sss & CallIndirect + 2 for bridge #define d_m3MemPageSize 65536 #define d_m3Reg0SlotAlias 30000 #define d_m3Fp0SlotAlias 30001 #define d_m3MaxSaneUtf8Length 2000 #define d_m3MaxSaneFunctionArgCount 1000 // still insane, but whatever #define d_externalKind_function 0 #define d_externalKind_table 1 #define d_externalKind_memory 2 #define d_externalKind_global 3 static const char * const c_waTypes [] = { "nil", "i32", "i64", "f32", "f64", "unknown" }; static const char * const c_waCompactTypes [] = { "_", "i", "I", "f", "F", "?" }; # if d_m3VerboseLogs M3Result m3Error (M3Result i_result, IM3Runtime i_runtime, IM3Module i_module, IM3Function i_function, const char * const i_file, u32 i_lineNum, const char * const i_errorMessage, ...); # define _m3Error(RESULT, RT, MOD, FUN, FILE, LINE, FORMAT, ...) \ m3Error (RESULT, RT, MOD, FUN, FILE, LINE, FORMAT, ##__VA_ARGS__) # else # define _m3Error(RESULT, RT, MOD, FUN, FILE, LINE, FORMAT, ...) (RESULT) # endif #define ErrorRuntime(RESULT, RUNTIME, FORMAT, ...) _m3Error (RESULT, RUNTIME, NULL, NULL, __FILE__, __LINE__, FORMAT, ##__VA_ARGS__) #define ErrorModule(RESULT, MOD, FORMAT, ...) _m3Error (RESULT, MOD->runtime, MOD, NULL, __FILE__, __LINE__, FORMAT, ##__VA_ARGS__) #define ErrorCompile(RESULT, COMP, FORMAT, ...) _m3Error (RESULT, COMP->runtime, COMP->module, NULL, __FILE__, __LINE__, FORMAT, ##__VA_ARGS__) #if d_m3LogNativeStack void m3StackCheckInit (); void m3StackCheck (); int m3StackGetMax (); #else #define m3StackCheckInit() #define m3StackCheck() #define m3StackGetMax() 0 #endif void m3_Abort (const char* message); M3Result m3_Malloc (void ** o_ptr, size_t i_size); M3Result m3_Realloc (void ** io_ptr, size_t i_newSize, size_t i_oldSize); void m3_Free (void ** io_ptr); M3Result m3_CopyMem (void ** o_to, const void * i_from, size_t i_size); #define m3Alloc(OPTR, STRUCT, NUM) m3_Malloc ((void **) OPTR, sizeof (STRUCT) * (NUM)) #define m3ReallocArray(PTR, STRUCT, NEW, OLD) m3_Realloc ((void **) (PTR), sizeof (STRUCT) * (NEW), sizeof (STRUCT) * (OLD)) #define m3Reallocate(_ptr, _newSize, _oldSize) m3_Realloc ((void **) _ptr, _newSize, _oldSize) #define m3Free(P) m3_Free ((void **)(& P)); #define m3CopyMem(_to, _from, _size) m3_CopyMem ((void **) _to, (void *) _from, _size) M3Result NormalizeType (u8 * o_type, i8 i_convolutedWasmType); bool IsIntType (u8 i_wasmType); bool IsFpType (u8 i_wasmType); bool Is64BitType (u8 i_m3Type); u32 SizeOfType (u8 i_m3Type); M3Result Read_u64 (u64 * o_value, bytes_t * io_bytes, cbytes_t i_end); M3Result Read_u32 (u32 * o_value, bytes_t * io_bytes, cbytes_t i_end); #if d_m3HasFloat || d_m3NoFloatDynamic M3Result Read_f64 (f64 * o_value, bytes_t * io_bytes, cbytes_t i_end); M3Result Read_f32 (f32 * o_value, bytes_t * io_bytes, cbytes_t i_end); #endif M3Result Read_u8 (u8 * o_value, bytes_t * io_bytes, cbytes_t i_end); M3Result ReadLebUnsigned (u64 * o_value, u32 i_maxNumBits, bytes_t * io_bytes, cbytes_t i_end); M3Result ReadLebSigned (i64 * o_value, u32 i_maxNumBits, bytes_t * io_bytes, cbytes_t i_end); M3Result ReadLEB_u32 (u32 * o_value, bytes_t * io_bytes, cbytes_t i_end); M3Result ReadLEB_u7 (u8 * o_value, bytes_t * io_bytes, cbytes_t i_end); M3Result ReadLEB_i7 (i8 * o_value, bytes_t * io_bytes, cbytes_t i_end); M3Result ReadLEB_i32 (i32 * o_value, bytes_t * io_bytes, cbytes_t i_end); M3Result ReadLEB_i64 (i64 * o_value, bytes_t * io_bytes, cbytes_t i_end); M3Result Read_utf8 (cstr_t * o_utf8, bytes_t * io_bytes, cbytes_t i_end); size_t SPrintArg (char * o_string, size_t i_n, m3stack_t i_sp, u8 i_type); void ReportError (IM3Runtime io_runtime, IM3Module i_module, IM3Function i_function, ccstr_t i_errorMessage, ccstr_t i_file, u32 i_lineNum); # if d_m3RecordBacktraces void PushBacktraceFrame (IM3Runtime io_runtime, pc_t i_pc); void FillBacktraceFunctionInfo (IM3Runtime io_runtime, IM3Function i_function); void ClearBacktrace (IM3Runtime io_runtime); # endif d_m3EndExternC #endif // m3_core_h