1 // 2 // m3_core.h 3 // 4 // Created by Steven Massey on 4/15/19. 5 // Copyright © 2019 Steven Massey. All rights reserved. 6 // 7 8 #ifndef m3_core_h 9 #define m3_core_h 10 11 #include <stdio.h> 12 #include <stdlib.h> 13 #include <stdbool.h> 14 #include <string.h> 15 #include <assert.h> 16 17 #include "wasm3.h" 18 #include "m3_config.h" 19 20 # if defined(__cplusplus) 21 # define d_m3BeginExternC extern "C" { 22 # define d_m3EndExternC } 23 # else 24 # define d_m3BeginExternC 25 # define d_m3EndExternC 26 # endif 27 28 d_m3BeginExternC 29 30 #define d_m3ImplementFloat (d_m3HasFloat || d_m3NoFloatDynamic) 31 32 #if !defined(d_m3ShortTypesDefined) 33 34 typedef uint64_t u64; 35 typedef int64_t i64; 36 typedef uint32_t u32; 37 typedef int32_t i32; 38 typedef uint16_t u16; 39 typedef int16_t i16; 40 typedef uint8_t u8; 41 typedef int8_t i8; 42 43 #if d_m3ImplementFloat 44 typedef double f64; 45 typedef float f32; 46 #endif 47 48 #endif // d_m3ShortTypesDefined 49 50 #define PRIf32 "f" 51 #define PRIf64 "lf" 52 53 typedef const void * m3ret_t; 54 typedef const void * voidptr_t; 55 typedef const char * cstr_t; 56 typedef const char * const ccstr_t; 57 typedef const u8 * bytes_t; 58 typedef const u8 * const cbytes_t; 59 60 typedef u16 m3opcode_t; 61 62 typedef i64 m3reg_t; 63 64 # if d_m3Use32BitSlots 65 typedef u32 m3slot_t; 66 # else 67 typedef u64 m3slot_t; 68 # endif 69 70 typedef m3slot_t * m3stack_t; 71 72 typedef 73 const void * const cvptr_t; 74 75 # if defined (DEBUG) 76 77 # define d_m3Log(CATEGORY, FMT, ...) printf (" %8s | " FMT, #CATEGORY, ##__VA_ARGS__); 78 79 # if d_m3LogParse 80 # define m3log_parse(CATEGORY, FMT, ...) d_m3Log(CATEGORY, FMT, ##__VA_ARGS__) 81 # else 82 # define m3log_parse(...) {} 83 # endif 84 85 # if d_m3LogCompile 86 # define m3log_compile(CATEGORY, FMT, ...) d_m3Log(CATEGORY, FMT, ##__VA_ARGS__) 87 # else 88 # define m3log_compile(...) {} 89 # endif 90 91 # if d_m3LogEmit 92 # define m3log_emit(CATEGORY, FMT, ...) d_m3Log(CATEGORY, FMT, ##__VA_ARGS__) 93 # else 94 # define m3log_emit(...) {} 95 # endif 96 97 # if d_m3LogCodePages 98 # define m3log_code(CATEGORY, FMT, ...) d_m3Log(CATEGORY, FMT, ##__VA_ARGS__) 99 # else 100 # define m3log_code(...) {} 101 # endif 102 103 # if d_m3LogModule 104 # define m3log_module(CATEGORY, FMT, ...) d_m3Log(CATEGORY, FMT, ##__VA_ARGS__) 105 # else 106 # define m3log_module(...) {} 107 # endif 108 109 # if d_m3LogRuntime 110 # define m3log_runtime(CATEGORY, FMT, ...) d_m3Log(CATEGORY, FMT, ##__VA_ARGS__) 111 # else 112 # define m3log_runtime(...) {} 113 # endif 114 115 # define m3log(CATEGORY, FMT, ...) m3log_##CATEGORY (CATEGORY, FMT "\n", ##__VA_ARGS__) 116 # else 117 # define d_m3Log(CATEGORY, FMT, ...) {} 118 # define m3log(CATEGORY, FMT, ...) {} 119 # endif 120 121 122 # if defined(ASSERTS) || (defined(DEBUG) && !defined(NASSERTS)) 123 # define d_m3Assert(ASS) if (!(ASS)) { printf("Assertion failed at %s:%d : %s\n", __FILE__, __LINE__, #ASS); abort(); } 124 # else 125 # define d_m3Assert(ASS) 126 # endif 127 128 typedef void /*const*/ * code_t; 129 typedef code_t const * /*__restrict__*/ pc_t; 130 131 132 typedef struct M3MemoryHeader 133 { 134 IM3Runtime runtime; 135 void * maxStack; 136 size_t length; 137 } 138 M3MemoryHeader; 139 140 struct M3CodeMappingPage; 141 142 typedef struct M3CodePageHeader 143 { 144 struct M3CodePage * next; 145 146 u32 lineIndex; 147 u32 numLines; 148 u32 sequence; // this is just used for debugging; could be removed 149 u32 usageCount; 150 151 # if d_m3RecordBacktraces 152 struct M3CodeMappingPage * mapping; 153 # endif // d_m3RecordBacktraces 154 } 155 M3CodePageHeader; 156 157 158 #define d_m3CodePageFreeLinesThreshold 4+2 // max is: select _sss & CallIndirect + 2 for bridge 159 160 #define d_m3MemPageSize 65536 161 162 #define d_m3Reg0SlotAlias 60000 163 #define d_m3Fp0SlotAlias (d_m3Reg0SlotAlias + 2) 164 165 #define d_m3MaxSaneTypesCount 100000 166 #define d_m3MaxSaneFunctionsCount 100000 167 #define d_m3MaxSaneImportsCount 10000 168 #define d_m3MaxSaneExportsCount 10000 169 #define d_m3MaxSaneGlobalsCount 100000 170 #define d_m3MaxSaneElementSegments 100000 171 #define d_m3MaxSaneDataSegments 100000 172 #define d_m3MaxSaneTableSize 100000 173 #define d_m3MaxSaneUtf8Length 10000 174 #define d_m3MaxSaneFunctionArgRetCount 1000 // still insane, but whatever 175 176 #define d_externalKind_function 0 177 #define d_externalKind_table 1 178 #define d_externalKind_memory 2 179 #define d_externalKind_global 3 180 181 static const char * const c_waTypes [] = { "nil", "i32", "i64", "f32", "f64", "unknown" }; 182 static const char * const c_waCompactTypes [] = { "_", "i", "I", "f", "F", "?" }; 183 184 185 # if d_m3VerboseErrorMessages 186 187 M3Result m3Error (M3Result i_result, IM3Runtime i_runtime, IM3Module i_module, IM3Function i_function, 188 const char * const i_file, u32 i_lineNum, const char * const i_errorMessage, ...); 189 190 # define _m3Error(RESULT, RT, MOD, FUN, FILE, LINE, FORMAT, ...) \ 191 m3Error (RESULT, RT, MOD, FUN, FILE, LINE, FORMAT, ##__VA_ARGS__) 192 193 # else 194 # define _m3Error(RESULT, RT, MOD, FUN, FILE, LINE, FORMAT, ...) (RESULT) 195 # endif 196 197 #define ErrorRuntime(RESULT, RUNTIME, FORMAT, ...) _m3Error (RESULT, RUNTIME, NULL, NULL, __FILE__, __LINE__, FORMAT, ##__VA_ARGS__) 198 #define ErrorModule(RESULT, MOD, FORMAT, ...) _m3Error (RESULT, MOD->runtime, MOD, NULL, __FILE__, __LINE__, FORMAT, ##__VA_ARGS__) 199 #define ErrorCompile(RESULT, COMP, FORMAT, ...) _m3Error (RESULT, COMP->runtime, COMP->module, NULL, __FILE__, __LINE__, FORMAT, ##__VA_ARGS__) 200 201 #if d_m3LogNativeStack 202 void m3StackCheckInit (); 203 void m3StackCheck (); 204 int m3StackGetMax (); 205 #else 206 #define m3StackCheckInit() 207 #define m3StackCheck() 208 #define m3StackGetMax() 0 209 #endif 210 211 void m3_Abort (const char* message); 212 void * m3_Malloc (size_t i_size); 213 void * m3_Realloc (void *i_ptr, size_t i_newSize, size_t i_oldSize); 214 void m3_FreeImpl (void * i_ptr); 215 void * m3_CopyMem (const void * i_from, size_t i_size); 216 217 #define m3_AllocStruct(STRUCT) (STRUCT *)m3_Malloc (sizeof (STRUCT)) 218 #define m3_AllocArray(STRUCT, NUM) (STRUCT *)m3_Malloc (sizeof (STRUCT) * (NUM)) 219 #define m3_ReallocArray(STRUCT, PTR, NEW, OLD) (STRUCT *)m3_Realloc ((void *)(PTR), sizeof (STRUCT) * (NEW), sizeof (STRUCT) * (OLD)) 220 #define m3_Free(P) do { m3_FreeImpl ((void*)(P)); (P) = NULL; } while(0) 221 222 M3Result NormalizeType (u8 * o_type, i8 i_convolutedWasmType); 223 224 bool IsIntType (u8 i_wasmType); 225 bool IsFpType (u8 i_wasmType); 226 bool Is64BitType (u8 i_m3Type); 227 u32 SizeOfType (u8 i_m3Type); 228 229 M3Result Read_u64 (u64 * o_value, bytes_t * io_bytes, cbytes_t i_end); 230 M3Result Read_u32 (u32 * o_value, bytes_t * io_bytes, cbytes_t i_end); 231 #if d_m3ImplementFloat 232 M3Result Read_f64 (f64 * o_value, bytes_t * io_bytes, cbytes_t i_end); 233 M3Result Read_f32 (f32 * o_value, bytes_t * io_bytes, cbytes_t i_end); 234 #endif 235 M3Result Read_u8 (u8 * o_value, bytes_t * io_bytes, cbytes_t i_end); 236 M3Result Read_opcode (m3opcode_t * o_value, bytes_t * io_bytes, cbytes_t i_end); 237 238 M3Result ReadLebUnsigned (u64 * o_value, u32 i_maxNumBits, bytes_t * io_bytes, cbytes_t i_end); 239 M3Result ReadLebSigned (i64 * o_value, u32 i_maxNumBits, bytes_t * io_bytes, cbytes_t i_end); 240 M3Result ReadLEB_u32 (u32 * o_value, bytes_t * io_bytes, cbytes_t i_end); 241 M3Result ReadLEB_u7 (u8 * o_value, bytes_t * io_bytes, cbytes_t i_end); 242 M3Result ReadLEB_i7 (i8 * o_value, bytes_t * io_bytes, cbytes_t i_end); 243 M3Result ReadLEB_i32 (i32 * o_value, bytes_t * io_bytes, cbytes_t i_end); 244 M3Result ReadLEB_i64 (i64 * o_value, bytes_t * io_bytes, cbytes_t i_end); 245 M3Result Read_utf8 (cstr_t * o_utf8, bytes_t * io_bytes, cbytes_t i_end); 246 247 cstr_t SPrintValue (void * i_value, u8 i_type); 248 size_t SPrintArg (char * o_string, size_t i_stringBufferSize, voidptr_t i_sp, u8 i_type); 249 250 void ReportError (IM3Runtime io_runtime, IM3Module i_module, IM3Function i_function, ccstr_t i_errorMessage, ccstr_t i_file, u32 i_lineNum); 251 252 # if d_m3RecordBacktraces 253 void PushBacktraceFrame (IM3Runtime io_runtime, pc_t i_pc); 254 void FillBacktraceFunctionInfo (IM3Runtime io_runtime, IM3Function i_function); 255 void ClearBacktrace (IM3Runtime io_runtime); 256 # endif 257 258 d_m3EndExternC 259 260 #endif // m3_core_h 261