Fixed maxStackSlots. MoveStackTopToRegister bug fix.

extensions
Steven Massey 4 years ago
parent a783bde17a
commit 031c21f496

@ -250,7 +250,7 @@ m3ApiRawFunction(m3_wasi_unstable_fd_prestat_dir_name)
if (runtime == NULL) { m3ApiReturn(__WASI_EINVAL); } if (runtime == NULL) { m3ApiReturn(__WASI_EINVAL); }
if (fd < 3 || fd >= PREOPEN_CNT) { m3ApiReturn(__WASI_EBADF); } if (fd < 3 || fd >= PREOPEN_CNT) { m3ApiReturn(__WASI_EBADF); }
int size = M3_MIN(strlen(preopen[fd].path), path_len); int size = m3_min (strlen(preopen[fd].path), path_len);
memcpy(path, preopen[fd].path, size); memcpy(path, preopen[fd].path, size);
m3ApiReturn(__WASI_ESUCCESS); m3ApiReturn(__WASI_ESUCCESS);
} }
@ -543,7 +543,7 @@ m3ApiRawFunction(m3_wasi_unstable_random_get)
ssize_t retlen = 0; ssize_t retlen = 0;
#if defined(__wasi__) || defined(__APPLE__) || defined(__ANDROID_API__) || defined(__OpenBSD__) #if defined(__wasi__) || defined(__APPLE__) || defined(__ANDROID_API__) || defined(__OpenBSD__)
size_t reqlen = M3_MIN(buflen, 256); size_t reqlen = m3_min (buflen, 256);
# if defined(__APPLE__) && (TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR) # if defined(__APPLE__) && (TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR)
retlen = SecRandomCopyBytes(kSecRandomDefault, reqlen, buf) < 0 ? -1 : reqlen; retlen = SecRandomCopyBytes(kSecRandomDefault, reqlen, buf) < 0 ? -1 : reqlen;
# else # else

@ -16,6 +16,8 @@
static const IM3Operation c_setSetOps [] = { NULL, op_SetSlot_i32, op_SetSlot_i64, op_SetSlot_f32, op_SetSlot_f64 }; static const IM3Operation c_setSetOps [] = { NULL, op_SetSlot_i32, op_SetSlot_i64, op_SetSlot_f32, op_SetSlot_f64 };
static const u16 c_slotUnused = 0xffff;
#define d_indent " | " #define d_indent " | "
// just want less letter and numbers to stare at down the way in the compiler table // just want less letter and numbers to stare at down the way in the compiler table
@ -142,8 +144,6 @@ bool IsStackTopInSlot (IM3Compilation o)
} }
static const u16 c_slotUnused = 0xffff;
u16 GetStackTopSlotIndex (IM3Compilation o) u16 GetStackTopSlotIndex (IM3Compilation o)
{ {
i16 i = GetStackTopIndex (o); d_m3Assert (i >= 0 or IsStackPolymorphic (o)); i16 i = GetStackTopIndex (o); d_m3Assert (i >= 0 or IsStackPolymorphic (o));
@ -167,7 +167,7 @@ bool IsValidSlot (u16 i_slot)
void MarkSlotAllocated (IM3Compilation o, u16 i_slot) void MarkSlotAllocated (IM3Compilation o, u16 i_slot)
{ d_m3Assert (o->m3Slots [i_slot] == 0); // shouldn't be already allocated { d_m3Assert (o->m3Slots [i_slot] == 0); // shouldn't be already allocated
o->m3Slots [i_slot] = 1; o->m3Slots [i_slot] = 1;
o->numAllocatedExecSlots++; o->numAllocatedSlots++;
} }
@ -217,7 +217,7 @@ void DeallocateSlot (IM3Compilation o, i16 i_slotIndex, u8 i_type)
for (u32 i = 0; i < GetTypeNumSlots (i_type); ++i, ++i_slotIndex) for (u32 i = 0; i < GetTypeNumSlots (i_type); ++i, ++i_slotIndex)
{ {
if (-- o->m3Slots [i_slotIndex] == 0) if (-- o->m3Slots [i_slotIndex] == 0)
o->numAllocatedExecSlots--; o->numAllocatedSlots--;
} }
} }
@ -262,7 +262,7 @@ u16 GetMaxExecSlot (IM3Compilation o)
{ {
u16 i = o->firstSlotIndex; u16 i = o->firstSlotIndex;
u32 allocated = o->numAllocatedExecSlots; u32 allocated = o->numAllocatedSlots;
while (i < d_m3MaxFunctionStackHeight) while (i < d_m3MaxFunctionStackHeight)
{ {
@ -349,7 +349,7 @@ _ (PreserveRegisterIfOccupied (o, c_m3Type_f64));
//---------------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------------
M3Result Push (IM3Compilation o, u8 i_type, i16 i_location) M3Result Push (IM3Compilation o, u8 i_type, u16 i_location)
{ {
M3Result result = m3Err_none; M3Result result = m3Err_none;
@ -357,13 +357,6 @@ M3Result Push (IM3Compilation o, u8 i_type, i16 i_location)
if (stackIndex < d_m3MaxFunctionStackHeight) if (stackIndex < d_m3MaxFunctionStackHeight)
{ {
if (o->function)
{
// op_Entry uses this value to track and detect stack overflow
if (stackIndex > o->function->maxStackSlots)
o->function->maxStackSlots = stackIndex;
}
o->wasmStack [stackIndex] = i_location; o->wasmStack [stackIndex] = i_location;
o->typeStack [stackIndex] = i_type; o->typeStack [stackIndex] = i_type;
@ -371,7 +364,17 @@ M3Result Push (IM3Compilation o, u8 i_type, i16 i_location)
{ {
u32 regSelect = IsFpRegisterLocation (i_location); u32 regSelect = IsFpRegisterLocation (i_location);
AllocateRegister (o, regSelect, stackIndex); AllocateRegister (o, regSelect, stackIndex);
} m3logif (stack, dump_type_stack (o)) }
else
{
if (o->function)
{
// op_Entry uses this value to track and detect stack overflow
o->function->maxStackSlots = m3_max (o->function->maxStackSlots, i_location + 1);
}
}
m3logif (stack, dump_type_stack (o))
} }
else result = m3Err_functionStackOverflow; else result = m3Err_functionStackOverflow;
@ -381,7 +384,7 @@ M3Result Push (IM3Compilation o, u8 i_type, i16 i_location)
M3Result PushRegister (IM3Compilation o, u8 i_type) M3Result PushRegister (IM3Compilation o, u8 i_type)
{ {
i16 location = IsFpType (i_type) ? d_m3Fp0SlotAlias : d_m3Reg0SlotAlias; d_m3Assert (i_type or IsStackPolymorphic (o)); u16 location = IsFpType (i_type) ? d_m3Fp0SlotAlias : d_m3Reg0SlotAlias; d_m3Assert (i_type or IsStackPolymorphic (o));
return Push (o, i_type, location); return Push (o, i_type, location);
} }
@ -656,13 +659,15 @@ _ (EmitOp (o, op));
M3Result MoveStackTopToRegister (IM3Compilation o) M3Result MoveStackTopToRegister (IM3Compilation o)
{ {
static const IM3Operation setRegisterOps [] = { NULL, op_SetRegister_i32, op_SetRegister_i64, op_SetRegister_f32, op_SetRegister_f64 };
M3Result result = m3Err_none; M3Result result = m3Err_none;
if (IsStackTopInSlot (o)) if (IsStackTopInSlot (o))
{ {
u8 type = GetStackTopType (o); u8 type = GetStackTopType (o);
static const IM3Operation setRegisterOps [] = { NULL, op_SetRegister_i32, op_SetRegister_i64, op_SetRegister_f32, op_SetRegister_f64 }; _ (PreserveRegisterIfOccupied (o, type));
IM3Operation op = setRegisterOps [type]; IM3Operation op = setRegisterOps [type];
@ -764,9 +769,9 @@ M3Result Compile_Const_i32 (IM3Compilation o, u8 i_opcode)
M3Result result; M3Result result;
i32 value; i32 value;
_ (ReadLEB_i32 (& value, & o->wasm, o->wasmEnd)); m3log (compile, d_indent "%s (const i32 = %" PRIi32 ")", get_indention_string (o), value); _ (ReadLEB_i32 (& value, & o->wasm, o->wasmEnd));
_ (PushConst (o, value, c_m3Type_i32)); _ (PushConst (o, value, c_m3Type_i32)); m3log (compile, d_indent "%s (const i32 = %" PRIi32 "; slot: %d)",
get_indention_string (o), value, GetStackTopSlotIndex (o));
_catch: return result; _catch: return result;
} }
@ -776,9 +781,9 @@ M3Result Compile_Const_i64 (IM3Compilation o, u8 i_opcode)
M3Result result; M3Result result;
i64 value; i64 value;
_ (ReadLEB_i64 (& value, & o->wasm, o->wasmEnd)); m3log (compile, d_indent "%s (const i64 = %" PRIi64 ")", get_indention_string (o), value); _ (ReadLEB_i64 (& value, & o->wasm, o->wasmEnd));
_ (PushConst (o, value, c_m3Type_i64)); _ (PushConst (o, value, c_m3Type_i64)); m3log (compile, d_indent "%s (const i64 = %" PRIi64 "; slot: %d)",
get_indention_string (o), value, GetStackTopSlotIndex (o));
_catch: return result; _catch: return result;
} }
@ -787,9 +792,9 @@ M3Result Compile_Const_f32 (IM3Compilation o, u8 i_opcode)
{ {
M3Result result; M3Result result;
union { u64 u; f32 f; } value = { 0 }; union { u32 u; f32 f; } value = { 0 };
_ (Read_f32 (& value.f, & o->wasm, o->wasmEnd)); m3log (compile, d_indent "%s (const f32 = %f)", get_indention_string (o), value); _ (Read_f32 (& value.f, & o->wasm, o->wasmEnd)); m3log (compile, d_indent "%s (const f32 = %f)", get_indention_string (o), value.f);
_ (PushConst (o, value.u, c_m3Type_f32)); _ (PushConst (o, value.u, c_m3Type_f32));
_catch: return result; _catch: return result;
@ -802,7 +807,7 @@ M3Result Compile_Const_f64 (IM3Compilation o, u8 i_opcode)
union { u64 u; f64 f; } value = { 0 }; union { u64 u; f64 f; } value = { 0 };
_ (Read_f64 (& value.f, & o->wasm, o->wasmEnd)); m3log (compile, d_indent "%s (const f64 = %lf)", get_indention_string (o), value); _ (Read_f64 (& value.f, & o->wasm, o->wasmEnd)); m3log (compile, d_indent "%s (const f64 = %lf)", get_indention_string (o), value.f);
_ (PushConst (o, value.u, c_m3Type_f64)); _ (PushConst (o, value.u, c_m3Type_f64));
_catch: return result; _catch: return result;
@ -1507,7 +1512,8 @@ _ (PushRegister (o, type));
M3Result Compile_Drop (IM3Compilation o, u8 i_opcode) M3Result Compile_Drop (IM3Compilation o, u8 i_opcode)
{ {
return Pop (o); M3Result result = Pop (o); m3logif (stack, dump_type_stack (o))
return result;
} }
@ -1650,7 +1656,7 @@ _ (ReadLEB_u32 (& memoryOffset, & o->wasm, o->wasmEnd));
m3log (compile, d_indent "%s (offset = %d)", get_indention_string (o), memoryOffset); m3log (compile, d_indent "%s (offset = %d)", get_indention_string (o), memoryOffset);
const M3OpInfo * op = & c_operations [i_opcode]; const M3OpInfo * op = & c_operations [i_opcode];
if (IsFpType (op->type)) // loading a float? if (IsFpType (op->type))
_ (PreserveRegisterIfOccupied (o, c_m3Type_f64)); _ (PreserveRegisterIfOccupied (o, c_m3Type_f64));
_ (Compile_Operator (o, i_opcode)); _ (Compile_Operator (o, i_opcode));
@ -2071,7 +2077,7 @@ M3Result Compile_ReserveConstants (IM3Compilation o)
// if constants overflow their reserved stack space, the compiler simply emits op_Const // if constants overflow their reserved stack space, the compiler simply emits op_Const
// operations as needed. Compiled expressions (global inits) don't pass through this // operations as needed. Compiled expressions (global inits) don't pass through this
// ReserveConstants function and thus always produce inline contants. // ReserveConstants function and thus always produce inline contants.
numConstants = M3_MIN (numConstants, d_m3MaxNumFunctionConstants); numConstants = m3_min (numConstants, d_m3MaxNumFunctionConstants);
u32 freeSlots = d_m3MaxFunctionStackHeight - o->constSlotIndex; u32 freeSlots = d_m3MaxFunctionStackHeight - o->constSlotIndex;
@ -2130,7 +2136,7 @@ _ (Compile_ReserveConstants (o));
// start tracking the max stack used (Push() also updates this value) so that op_Entry can precisely detect stack overflow // start tracking the max stack used (Push() also updates this value) so that op_Entry can precisely detect stack overflow
o->function->maxStackSlots = o->firstSlotIndex; o->function->maxStackSlots = o->firstSlotIndex;
o->numAllocatedExecSlots = 0; // this var only tracks dynamic slots so clear local+constant allocations o->numAllocatedSlots = 0; // this var only tracks dynamic slots so clear local+constant allocations
o->block.initStackIndex = o->stackIndex; o->block.initStackIndex = o->stackIndex;
_ (EmitOp (o, op_Entry)); _ (EmitOp (o, op_Entry));

@ -98,7 +98,7 @@ typedef struct
// 'm3Slots' contains allocation usage counts // 'm3Slots' contains allocation usage counts
u8 m3Slots [d_m3MaxFunctionStackHeight]; u8 m3Slots [d_m3MaxFunctionStackHeight];
u16 numAllocatedExecSlots; u16 numAllocatedSlots;
u16 regStackIndexPlusOne [2]; u16 regStackIndexPlusOne [2];
@ -152,11 +152,6 @@ bool IsIntRegisterLocation (i16 i_location);
bool IsStackPolymorphic (IM3Compilation o); bool IsStackPolymorphic (IM3Compilation o);
M3Result EmitOp (IM3Compilation o, IM3Operation i_operation);
void EmitConstant (IM3Compilation o, const u64 immediate);
M3Result Push (IM3Compilation o, u8 i_waType, i16 i_location);
void EmitPointer (IM3Compilation o, const void * const i_immediate);
M3Result CompileBlock (IM3Compilation io, u8 i_blockType, u8 i_blockOpcode); M3Result CompileBlock (IM3Compilation io, u8 i_blockType, u8 i_blockOpcode);
M3Result Compile_BlockStatements (IM3Compilation io); M3Result Compile_BlockStatements (IM3Compilation io);

@ -21,6 +21,8 @@
# define d_m3MaxFunctionStackHeight 2000 # define d_m3MaxFunctionStackHeight 2000
# endif # endif
#define d_m3MaxNumFunctionConstants 60
# ifndef d_m3LogOutput # ifndef d_m3LogOutput
# define d_m3LogOutput 1 # define d_m3LogOutput 1
# endif # endif
@ -52,16 +54,16 @@
// m3log (...) ---------------------------------------------------------------- // m3log (...) ----------------------------------------------------------------
# define d_m3LogParse 0 # define d_m3LogParse 0 // .wasm binary decoding info
# define d_m3LogCompile 0 # define d_m3LogModule 0 // Wasm module info
# define d_m3LogWasmStack 0 # define d_m3LogCompile 0 // wasm -> metacode generation phase
# define d_m3LogEmit 0 # define d_m3LogWasmStack 0 // dump the wasm stack when pushed or popped
# define d_m3LogCodePages 0 # define d_m3LogEmit 0 // metacode generation info
# define d_m3LogModule 0 # define d_m3LogCodePages 0 // dump metacode pages when released
# define d_m3LogRuntime 0 # define d_m3LogExec 0 // low-level interpreter specific logs
# define d_m3LogExec 0 # define d_m3LogRuntime 0 // higher-level runtime information
# define d_m3LogStackTrace 0 # define d_m3LogStackTrace 0 // dump the call stack when traps occur
# define d_m3LogNativeStack 0 # define d_m3LogNativeStack 0 // track the memory usage of the C-stack
// other ---------------------------------------------------------------------- // other ----------------------------------------------------------------------

@ -178,11 +178,11 @@
# define M3_WEAK __attribute__((weak)) # define M3_WEAK __attribute__((weak))
# endif # endif
# ifndef M3_MIN # ifndef m3_min
# define M3_MIN(A,B) (((A) < (B)) ? (A) : (B)) # define m3_min(A,B) (((A) < (B)) ? (A) : (B))
# endif # endif
# ifndef M3_MAX # ifndef m3_max
# define M3_MAX(A,B) (((A) > (B)) ? (A) : (B)) # define m3_max(A,B) (((A) > (B)) ? (A) : (B))
# endif # endif
#define M3_INIT(field) memset(&field, 0, sizeof(field)) #define M3_INIT(field) memset(&field, 0, sizeof(field))

@ -173,7 +173,7 @@ void m3StackCheck ()
size_t addr = (size_t)&stack; size_t addr = (size_t)&stack;
size_t stackEnd = stack_end; size_t stackEnd = stack_end;
stack_end = M3_MIN(stack_end, addr); stack_end = m3_min (stack_end, addr);
// if (stackEnd != stack_end) // if (stackEnd != stack_end)
// printf ("maxStack: %ld\n", m3StackGetMax ()); // printf ("maxStack: %ld\n", m3StackGetMax ());

@ -154,10 +154,8 @@ M3CodePageHeader;
#define d_m3MemPageSize 65536 #define d_m3MemPageSize 65536
#define d_m3Reg0SlotAlias d_m3MaxFunctionStackHeight + 1 #define d_m3Reg0SlotAlias 30000
#define d_m3Fp0SlotAlias d_m3MaxFunctionStackHeight + 2 #define d_m3Fp0SlotAlias 30001
#define d_m3MaxNumFunctionConstants 60
#define d_m3MaxSaneUtf8Length 2000 #define d_m3MaxSaneUtf8Length 2000

@ -298,7 +298,7 @@ M3Result ResizeMemory (IM3Runtime io_runtime, u32 i_numPages)
// Limit the amount of memory that gets allocated // Limit the amount of memory that gets allocated
if (io_runtime->memoryLimit) { if (io_runtime->memoryLimit) {
numPageBytes = M3_MIN(numPageBytes, io_runtime->memoryLimit); numPageBytes = m3_min (numPageBytes, io_runtime->memoryLimit);
} }
size_t numBytes = numPageBytes + sizeof (M3MemoryHeader); size_t numBytes = numPageBytes + sizeof (M3MemoryHeader);
@ -321,7 +321,7 @@ M3Result ResizeMemory (IM3Runtime io_runtime, u32 i_numPages)
memory->mallocated->maxStack = (m3reg_t *) io_runtime->stack + io_runtime->numStackSlots; memory->mallocated->maxStack = (m3reg_t *) io_runtime->stack + io_runtime->numStackSlots;
m3log (runtime, "resized old: %p; mem: %p; length: %z; pages: %d", oldMallocated, memory->mallocated, memory->mallocated->length, memory->numPages); m3log (runtime, "resized old: %p; mem: %p; length: %zu; pages: %d", oldMallocated, memory->mallocated, memory->mallocated->length, memory->numPages);
} }
else result = m3Err_mallocFailed; else result = m3Err_mallocFailed;
} }

@ -92,7 +92,7 @@ size_t SPrintArg (char * o_string, size_t i_n, m3stack_t i_sp, u8 i_type)
else if (i_type == c_m3Type_f64) else if (i_type == c_m3Type_f64)
len = snprintf (o_string, i_n, "%lf", * (f64 *) i_sp); len = snprintf (o_string, i_n, "%lf", * (f64 *) i_sp);
len = M3_MAX (0, len); len = m3_max (0, len);
return len; return len;
} }
@ -105,7 +105,7 @@ cstr_t SPrintFunctionArgList (IM3Function i_function, m3stack_t i_sp)
char * s = string; char * s = string;
ccstr_t e = string + sizeof(string) - 1; ccstr_t e = string + sizeof(string) - 1;
s += M3_MAX (0, snprintf (s, e-s, "(")); s += m3_max (0, snprintf (s, e-s, "("));
IM3FuncType funcType = i_function->funcType; IM3FuncType funcType = i_function->funcType;
if (funcType) if (funcType)
@ -117,17 +117,17 @@ cstr_t SPrintFunctionArgList (IM3Function i_function, m3stack_t i_sp)
{ {
u8 type = types [i]; u8 type = types [i];
s += M3_MAX (0, snprintf (s, e-s, "%s: ", c_waTypes [type])); s += m3_max (0, snprintf (s, e-s, "%s: ", c_waTypes [type]));
s += SPrintArg (s, e-s, i_sp + i, type); s += SPrintArg (s, e-s, i_sp + i, type);
if (i != numArgs - 1) if (i != numArgs - 1)
s += M3_MAX (0, snprintf (s, e-s, ", ")); s += m3_max (0, snprintf (s, e-s, ", "));
} }
} }
else printf ("null signature"); else printf ("null signature");
s += M3_MAX (0, snprintf (s, e-s, ")")); s += m3_max (0, snprintf (s, e-s, ")"));
return string; return string;
} }

@ -235,7 +235,7 @@ M3Result ParseSection_Start (IM3Module io_module, bytes_t i_bytes, cbytes_t i_
M3Result result = m3Err_none; M3Result result = m3Err_none;
u32 startFuncIndex; u32 startFuncIndex;
_ (ReadLEB_u32 (& startFuncIndex, & i_bytes, i_end)); m3log (parse, "** Start Function: %d", startFunc); _ (ReadLEB_u32 (& startFuncIndex, & i_bytes, i_end)); m3log (parse, "** Start Function: %d", startFuncIndex);
if (startFuncIndex < io_module->numFunctions) if (startFuncIndex < io_module->numFunctions)
{ {
@ -310,22 +310,22 @@ _ (ReadLEB_u32 (& size, & i_bytes, i_end));
{ {
const u8 * start = ptr; const u8 * start = ptr;
u32 numLocals; u32 numLocalBlocks;
_ (ReadLEB_u32 (& numLocals, & ptr, i_end)); m3log (parse, " - func size: %d; locals: %d", size, numLocals); _ (ReadLEB_u32 (& numLocalBlocks, & ptr, i_end)); m3log (parse, " - func size: %d; local blocks: %d", size, numLocalBlocks);
u32 numLocalVars = 0; u32 numLocals = 0;
for (u32 l = 0; l < numLocals; ++l) for (u32 l = 0; l < numLocalBlocks; ++l)
{ {
u32 varCount; u32 varCount;
i8 varType; i8 wasmType;
u8 normalizedType; u8 normalType;
_ (ReadLEB_u32 (& varCount, & ptr, i_end)); _ (ReadLEB_u32 (& varCount, & ptr, i_end));
_ (ReadLEB_i7 (& varType, & ptr, i_end)); _ (ReadLEB_i7 (& wasmType, & ptr, i_end));
_ (NormalizeType (& normalizedType, varType)); _ (NormalizeType (& normalType, wasmType));
numLocalVars += varCount; m3log (parse, " - %d locals; type: '%s'", varCount, c_waTypes [-varType]); numLocals += varCount; m3log (parse, " - %d locals; type: '%s'", varCount, c_waTypes [normalType]);
} }
IM3Function func = Module_GetFunction (io_module, f + io_module->numImports); IM3Function func = Module_GetFunction (io_module, f + io_module->numImports);
@ -333,7 +333,7 @@ _ (NormalizeType (& normalizedType, varType));
func->module = io_module; func->module = io_module;
func->wasm = start; func->wasm = start;
func->wasmEnd = i_bytes; func->wasmEnd = i_bytes;
func->numLocals = numLocalVars; func->numLocals = numLocals;
} }
else _throw (m3Err_wasmSectionOverrun); else _throw (m3Err_wasmSectionOverrun);
} }

@ -123,7 +123,7 @@ d_m3ErrorConst (functionImportMissing, "missing imported function")
// compilation errors // compilation errors
d_m3ErrorConst (noCompiler, "no compiler found for opcode") d_m3ErrorConst (noCompiler, "no compiler found for opcode")
d_m3ErrorConst (unknownOpcode, "unknown opcode") d_m3ErrorConst (unknownOpcode, "unknown opcode")
d_m3ErrorConst (functionStackOverflow, "compiling function overrun its stack height limit") d_m3ErrorConst (functionStackOverflow, "compiling function overran its stack height limit")
d_m3ErrorConst (functionStackUnderrun, "compiling function underran the stack") d_m3ErrorConst (functionStackUnderrun, "compiling function underran the stack")
d_m3ErrorConst (mallocFailedCodePage, "memory allocation failed when acquiring a new M3 code page") d_m3ErrorConst (mallocFailedCodePage, "memory allocation failed when acquiring a new M3 code page")
d_m3ErrorConst (settingImmutableGlobal, "attempting to set an immutable global") d_m3ErrorConst (settingImmutableGlobal, "attempting to set an immutable global")

Loading…
Cancel
Save