Merge branch 'main' into multi-value

extensions
Steven Massey 3 years ago
commit 7608ca25e6

@ -92,10 +92,19 @@ M3Result link_all (IM3Module module)
return res;
}
const char* modname_from_fn(const char* fn)
{
const char* off = strrchr(fn, '/');
if (off) return off+1;
off = strrchr(fn, '\\');
if (off) return off+1;
return fn;
}
M3Result repl_load (const char* fn)
{
M3Result result = m3Err_none;
IM3Module module = NULL;
u8* wasm = NULL;
u32 fsize = 0;
@ -129,13 +138,14 @@ M3Result repl_load (const char* fn)
fclose (f);
f = NULL;
IM3Module module;
result = m3_ParseModule (env, &module, wasm, fsize);
if (result) goto on_error;
result = m3_LoadModule (runtime, module);
if (result) goto on_error;
m3_SetModuleName(module, modname_from_fn(fn));
result = link_all (module);
if (result) goto on_error;
@ -144,7 +154,9 @@ M3Result repl_load (const char* fn)
}
return result;
on_error:
m3_FreeModule(module);
if (wasm) free(wasm);
if (f) fclose(f);

@ -32,16 +32,20 @@
#define m3ApiSuccess() { return m3Err_none; }
# if defined(M3_BIG_ENDIAN)
# define m3ApiReadMem8(ptr) (* (u8 *)(ptr))
# define m3ApiReadMem16(ptr) __builtin_bswap16((* (u16 *)(ptr)))
# define m3ApiReadMem32(ptr) __builtin_bswap32((* (u32 *)(ptr)))
# define m3ApiReadMem64(ptr) __builtin_bswap64((* (u64 *)(ptr)))
# define m3ApiWriteMem8(ptr, val) { * (u8 *)(ptr) = (val); }
# define m3ApiWriteMem16(ptr, val) { * (u16 *)(ptr) = __builtin_bswap16((val)); }
# define m3ApiWriteMem32(ptr, val) { * (u32 *)(ptr) = __builtin_bswap32((val)); }
# define m3ApiWriteMem64(ptr, val) { * (u64 *)(ptr) = __builtin_bswap64((val)); }
# else
# define m3ApiReadMem8(ptr) (* (u8 *)(ptr))
# define m3ApiReadMem16(ptr) (* (u16 *)(ptr))
# define m3ApiReadMem32(ptr) (* (u32 *)(ptr))
# define m3ApiReadMem64(ptr) (* (u64 *)(ptr))
# define m3ApiWriteMem8(ptr, val) { * (u8 *)(ptr) = (val); }
# define m3ApiWriteMem16(ptr, val) { * (u16 *)(ptr) = (val); }
# define m3ApiWriteMem32(ptr, val) { * (u32 *)(ptr) = (val); }
# define m3ApiWriteMem64(ptr, val) { * (u64 *)(ptr) = (val); }

@ -362,7 +362,7 @@ u16 GetMaxUsedSlotPlusOne (IM3Compilation o)
o->slotMaxAllocatedIndexPlusOne--;
}
# ifdef DEBUG
u16 maxSlot = o->slotMaxAllocatedIndexPlusOne;
while (maxSlot < d_m3MaxFunctionSlots)
@ -465,8 +465,8 @@ M3Result Push (IM3Compilation o, u8 i_type, u16 i_slot)
u32 regSelect = IsFpRegisterSlotAlias (i_slot);
AllocateRegister (o, regSelect, stackIndex);
}
if (d_m3LogWasmStack) dump_type_stack (o);
if (d_m3LogWasmStack) dump_type_stack (o);
}
else result = m3Err_functionStackOverflow;
@ -1062,7 +1062,8 @@ _ (CopyStackIndexToSlot (o, returnSlot, stackTop--));
_ (Pop (o));
}
}
_catch: return result;
_catch: return result;
}
@ -1482,7 +1483,7 @@ _ (GetBlockScope (o, & scope, target));
// create a ContinueLoop operation on a fresh page
_ (AcquireCompilationCodePage (o, & continueOpPage));
pc_t startPC = GetPagePC (continueOpPage);
IM3CodePage savedPage = o->page;
o->page = continueOpPage;
@ -1514,7 +1515,7 @@ _ (EmitPatchingBranch (o, scope));
}
}
}
ReleaseCompilationCodePage (o); // FIX: continueOpPage can get lost if thrown
o->page = savedPage;
@ -2367,7 +2368,7 @@ const M3OpInfo c_operations [] =
d_m3DebugOp (CopySlot_32), d_m3DebugOp (PreserveCopySlot_32), d_m3DebugOp (If_s), d_m3DebugOp (BranchIfPrologue_s),
d_m3DebugOp (CopySlot_64), d_m3DebugOp (PreserveCopySlot_64), d_m3DebugOp (If_r), d_m3DebugOp (BranchIfPrologue_r),
d_m3DebugOp (Select_i32_rss), d_m3DebugOp (Select_i32_srs), d_m3DebugOp (Select_i32_ssr), d_m3DebugOp (Select_i32_sss),
d_m3DebugOp (Select_i64_rss), d_m3DebugOp (Select_i64_srs), d_m3DebugOp (Select_i64_ssr), d_m3DebugOp (Select_i64_sss),
@ -2744,7 +2745,7 @@ _ (CompileLocals (o));
_ (ReserveConstants (o));
// start tracking the max stack used (Push() also updates this value) so that op_Entry can precisely detect stack overflow
o->function->maxStackSlots = o->slotMaxAllocatedIndexPlusOne = o->slotFirstDynamicIndex;
o->maxStackSlots = o->slotMaxAllocatedIndexPlusOne = o->slotFirstDynamicIndex;
o->block.blockStackIndex = o->stackFirstDynamicIndex = o->stackIndex; m3log (compile, "start stack index: %d",
(u32) o->stackFirstDynamicIndex);
@ -2757,6 +2758,7 @@ _ (CompileBlockStatements (o));
_throwif(m3Err_wasmMalformed, o->previousOpcode != c_waOp_end);
io_function->compiled = pc;
io_function->maxStackSlots = o->maxStackSlots;
u16 numConstantSlots = o->slotMaxConstIndex - o->slotFirstConstIndex; m3log (compile, "unique constant slots: %d; unused slots: %d",
numConstantSlots, o->slotFirstDynamicIndex - o->slotMaxConstIndex);

@ -91,6 +91,8 @@ typedef struct
u16 slotFirstLocalIndex;
u16 slotFirstDynamicIndex; // numArgs + numLocals + numReservedConstants. the first mutable slot available to the compiler.
u16 maxStackSlots;
m3slot_t constants [d_m3MaxConstantTableSize];
// 'wasmStack' holds slot locations

@ -117,7 +117,7 @@ void * m3_Malloc (size_t i_size)
void m3_FreeImpl (void * io_ptr)
{
// if (io_ptr) printf("== free %p\n", io_ptr);
free ((void*)io_ptr);
free (io_ptr);
}
void * m3_Realloc (void * i_ptr, size_t i_newSize, size_t i_oldSize)

@ -286,6 +286,10 @@ M3Result EvaluateExpression (IM3Module i_module, void * o_expressed, u8 i_type
pc_t m3code = GetPagePC (o->page);
result = CompileBlock (o, ftype, c_waOp_block);
if (not result && o->maxStackSlots >= runtime.numStackSlots) {
result = m3Err_trapStackOverflow;
}
if (not result)
{
m3ret_t r = Call (m3code, stack, NULL, d_m3OpDefaultArgs);
@ -542,28 +546,32 @@ M3Result m3_LoadModule (IM3Runtime io_runtime, IM3Module io_module)
{
M3Result result = m3Err_none;
if (not io_module->runtime)
{
io_module->runtime = io_runtime;
M3Memory * memory = & io_runtime->memory;
if (UNLIKELY(io_module->runtime)) {
return m3Err_moduleAlreadyLinked;
}
_ (InitMemory (io_runtime, io_module));
_ (InitGlobals (io_module));
_ (InitDataSegments (memory, io_module));
_ (InitElements (io_module));
io_module->runtime = io_runtime;
M3Memory * memory = & io_runtime->memory;
io_module->next = io_runtime->modules;
io_runtime->modules = io_module;
_ (InitMemory (io_runtime, io_module));
_ (InitGlobals (io_module));
_ (InitDataSegments (memory, io_module));
_ (InitElements (io_module));
// Start func might use imported functions, which are not liked here yet,
// so it will be called before a function call is attempted (in m3_FindFuSnction)
}
else result = m3Err_moduleAlreadyLinked;
// Start func might use imported functions, which are not liked here yet,
// so it will be called before a function call is attempted (in m3_FindFunction)
if (result)
io_module->runtime = NULL;
#ifdef DEBUG
Module_GenerateNames(io_module);
#endif
_catch: return result;
io_module->next = io_runtime->modules;
io_runtime->modules = io_module;
return result; // ok
_catch:
io_module->runtime = NULL;
return result;
}
IM3Global m3_FindGlobal (IM3Module io_module,

@ -123,6 +123,8 @@ M3Result Module_AddGlobal (IM3Module io_module, IM
M3Result Module_AddFunction (IM3Module io_module, u32 i_typeIndex, IM3ImportInfo i_importInfo /* can be null */);
IM3Function Module_GetFunction (IM3Module i_module, u32 i_functionIndex);
void Module_GenerateNames (IM3Module i_module);
void FreeImportInfo (M3ImportInfo * i_info);
//---------------------------------------------------------------------------------------------------------------------------------

@ -744,13 +744,7 @@ d_m3Op (Entry)
}
#if d_m3EnableStrace >= 2
u16 numNames = 0;
cstr_t *names = GetFunctionNames(function, &numNames);
if (numNames) {
d_m3TracePrint("%s %s {", names[0], SPrintFunctionArgList (function, _sp));
} else {
d_m3TracePrint("$%d %s {", function->index, SPrintFunctionArgList (function, _sp));
}
d_m3TracePrint("%s %s {", m3_GetFunctionName(function), SPrintFunctionArgList (function, _sp));
trace_rt->callDepth++;
#endif

@ -63,7 +63,7 @@ typedef struct M3Function
u32 hits;
#endif
# if d_m3EnableStrace >= 2 || d_m3LogCompile
# if d_m3LogCompile
u32 index;
# endif

@ -250,24 +250,20 @@ d_m3Decoder (BranchTable)
{
u32 slot = fetch (u32);
sprintf (o_string, "slot: %" PRIu32 "; targets: ", slot);
o_string += sprintf (o_string, "slot: %" PRIu32 "; targets: ", slot);
// IM3Function function = fetch2 (IM3Function);
i32 targets = fetch (i32);
char str [1000];
for (i32 i = 0; i < targets; ++i)
{
pc_t addr = fetch (pc_t);
sprintf (str, "%" PRIi32 "=%p, ", i, addr);
strcat (o_string, str);
o_string += sprintf (o_string, "%" PRIi32 "=%p, ", i, addr);
}
pc_t addr = fetch (pc_t);
sprintf (str, "def=%p ", addr);
strcat (o_string, str);
sprintf (o_string, "def=%p ", addr);
}
@ -315,7 +311,7 @@ void dump_code_page (IM3CodePage i_codePage, pc_t i_startPC)
if (i.info)
{
char infoString [1000] = { 0 };
char infoString [8*1024] = { 0 };
DecodeOperation (infoString, i.opcode, op, i.info, & pc);
@ -424,7 +420,7 @@ void dump_type_stack (IM3Compilation o)
// d_m3Assert (regAllocated [r] == 0); // reg allocation & stack out of sync
u16 maxSlot = GetMaxUsedSlotPlusOne (o);
if (maxSlot > o->slotFirstDynamicIndex)
{
d_m3Log (stack, " -");
@ -445,7 +441,7 @@ void dump_type_stack (IM3Compilation o)
{
printf ("%3d|", o->m3Slots [i]);
}
printf ("\n");
}
d_m3Log(stack, "\n");

@ -37,9 +37,6 @@ void m3_FreeModule (IM3Module i_module)
for (u32 i = 0; i < i_module->numGlobals; ++i)
{
m3_Free (i_module->globals[i].name);
}
for (u32 i = 0; i < i_module->numGlobals; ++i)
{
FreeImportInfo(&(i_module->globals[i].import));
}
m3_Free (i_module->globals);
@ -84,15 +81,15 @@ _try {
IM3Function func = Module_GetFunction (io_module, index);
func->funcType = ft;
#if d_m3EnableStrace >= 2 || d_m3LogCompile
# if d_m3LogCompile
func->index = index;
#endif
# endif
if (i_importInfo and func->numNames == 0)
{
func->import = * i_importInfo;
func->numNames = 1;
func->names[0] = i_importInfo->fieldUtf8;
func->numNames = 1;
}
m3log (module, " added function: %3d; sig: %d", index, i_typeIndex);
@ -101,6 +98,32 @@ _try {
return result;
}
void Module_GenerateNames (IM3Module i_module)
{
for (u32 i = 0; i < i_module->numFunctions; ++i)
{
IM3Function func = & i_module->functions [i];
if (func->numNames == 0)
{
char* buff = m3_AllocArray(char, 16);
snprintf(buff, 16, "$func%d", i);
func->names[0] = buff;
func->numNames = 1;
}
}
for (u32 i = 0; i < i_module->numGlobals; ++i)
{
IM3Global global = & i_module->globals [i];
if (global->name == NULL)
{
char* buff = m3_AllocArray(char, 16);
snprintf(buff, 16, "$global%d", i);
global->name = buff;
}
}
}
IM3Function Module_GetFunction (IM3Module i_module, u32 i_functionIndex)
{
@ -119,11 +142,16 @@ IM3Function Module_GetFunction (IM3Module i_module, u32 i_functionIndex)
const char* m3_GetModuleName (IM3Module i_module)
{
if (!i_module || !i_module->name)
return "<unknown>";
return ".unnamed";
return i_module->name;
}
void m3_SetModuleName (IM3Module i_module, const char* name)
{
if (i_module) i_module->name = name;
}
IM3Runtime m3_GetModuleRuntime (IM3Module i_module)
{
return i_module ? i_module->runtime : NULL;

@ -127,6 +127,8 @@ _ (ReadLEB_u32 (& numFunctions, & i_bytes, i_end));
_throwif("too many functions", numFunctions > d_m3MaxSaneFunctionsCount);
// TODO: prealloc functions
for (u32 i = 0; i < numFunctions; ++i)
{
u32 funcTypeIndex;
@ -236,18 +238,19 @@ _ (ReadLEB_u32 (& index, & i_bytes, i_end));
if (exportKind == d_externalKind_function)
{
_throwif(m3Err_wasmMalformed, index >= io_module->numFunctions);
u16 numNames = io_module->functions [index].numNames;
if (numNames < d_m3MaxDuplicateFunctionImpl)
IM3Function func = &(io_module->functions [index]);
if (func->numNames < d_m3MaxDuplicateFunctionImpl)
{
io_module->functions [index].numNames++;
io_module->functions [index].names[numNames] = utf8;
func->names[func->numNames++] = utf8;
utf8 = NULL; // ownership transferred to M3Function
}
}
else if (exportKind == d_externalKind_global)
{
_throwif(m3Err_wasmMalformed, index >= io_module->numGlobals);
io_module->globals[index].name = utf8;
IM3Global global = &(io_module->globals [index]);
m3_Free (global->name);
global->name = utf8;
utf8 = NULL; // ownership transferred to M3Global
}
@ -506,10 +509,11 @@ _ (Read_utf8 (& name, & i_bytes, i_end));
if (index < io_module->numFunctions)
{
if (io_module->functions [index].numNames == 0)
IM3Function func = &(io_module->functions [index]);
if (func->numNames == 0)
{
io_module->functions [index].numNames = 1;
io_module->functions [index].names[0] = name; m3log (parse, " naming function%5d: %s", index, name);
func->names[0] = name; m3log (parse, " naming function%5d: %s", index, name);
func->numNames = 1;
name = NULL; // transfer ownership
}
// else m3log (parse, "prenamed: %s", io_module->functions [index].name);

@ -246,6 +246,7 @@ d_m3ErrorConst (trapStackOverflow, "[trap] stack overflow")
const void * i_userdata);
const char* m3_GetModuleName (IM3Module i_module);
void m3_SetModuleName (IM3Module i_module, const char* name);
IM3Runtime m3_GetModuleRuntime (IM3Module i_module);
//-------------------------------------------------------------------------------------------------------------------------------

@ -65,7 +65,7 @@ commands_full = [
"args": ["16", "64"],
"expect_sha1": "d85df3561eb15f6f0e6f20d5640e8e1306222c6d"
}, {
"skip": True, # Fails on Windows-uvwasi, on CI only (CNR locally)
"skip": True, # TODO
"name": "mal",
"wasm": "./wasi/mal/mal.wasm",
"args": ["./wasi/mal/test-fib.mal", "16"],
@ -127,6 +127,7 @@ commands_fast = [
"args": ["4", "32"],
"expect_sha1": "ea05d85998b2f453b588ef76a1256215bf9b851c"
}, {
"skip": True, # TODO
"name": "mal",
"wasm": "./wasi/mal/mal.wasm",
"args": ["./wasi/mal/test-fib.mal", "16"],
@ -176,9 +177,9 @@ for cmd in commands:
stats.timeout += 1
fail("Timeout")
continue
except subprocess.CalledProcessError:
except subprocess.CalledProcessError as e:
stats.crashed += 1
fail("Crashed")
fail(f"Exited with error code {e.returncode}")
continue
if "expect_sha1" in cmd:

Loading…
Cancel
Save