From 1d412aafd243248dc3e7ac8a307fe04990294e34 Mon Sep 17 00:00:00 2001 From: Steven Massey Date: Thu, 8 Apr 2021 16:38:54 -0700 Subject: [PATCH] multi-return prep --- source/m3_compile.c | 38 ++++++++++++++++++++++---------------- source/m3_env.c | 22 +++++++++++++++++++--- source/m3_exec.h | 2 +- source/m3_function.h | 2 +- source/m3_info.c | 2 +- 5 files changed, 44 insertions(+), 22 deletions(-) diff --git a/source/m3_compile.c b/source/m3_compile.c index 0b16f93..450d81d 100644 --- a/source/m3_compile.c +++ b/source/m3_compile.c @@ -1384,11 +1384,11 @@ _try { _ (Pop (o)); u32 numArgs = i_type->numArgs; + u32 numRets = i_type->numRets; + // args are 64-bit aligned u32 slotsPerArg = sizeof (u64) / sizeof (m3slot_t); - - // args are 64-bit aligned - u16 argTop = topSlot + numArgs * slotsPerArg; + u16 argTop = topSlot + (numArgs + numRets * 1) * slotsPerArg; while (numArgs--) { @@ -1399,7 +1399,7 @@ _ (Pop (o)); if (i_type->numRets) { MarkSlotAllocated (o, topSlot); -_ (Push (o, GetSingleRetType(i_type), topSlot)); +_ (Push (o, GetSingleRetType (i_type), topSlot)); } } _catch: return result; @@ -1421,8 +1421,6 @@ _ (ReadLEB_u32 (& functionIndex, & o->wasm, o->wasmEnd)); get_indention_string (o), m3_GetFunctionName (function), function->funcType->numArgs); if (function->module) { - // OPTZ: could avoid arg copy when args are already sequential and at top - u16 slotTop; _ (CompileCallArgsAndReturn (o, & slotTop, function->funcType, false)); @@ -2357,11 +2355,11 @@ void SetupCompilation (IM3Compilation o) M3Result Compile_Function (IM3Function io_function) { - IM3FuncType ft = io_function->funcType; + IM3FuncType funcType = io_function->funcType; M3Result result = m3Err_none; m3log (compile, "compiling: '%s'; wasm-size: %d; numArgs: %d; return: %s", m3_GetFunctionName(io_function), (u32) (io_function->wasmEnd - io_function->wasm), GetFunctionNumArgs (io_function), - c_waTypes [GetSingleRetType(ft)]); + c_waTypes [GetSingleRetType(funcType)]); IM3Runtime runtime = io_function->module->runtime; IM3Compilation o = & runtime->compilation; d_m3Assert (d_m3MaxFunctionSlots >= d_m3MaxFunctionStackHeight * (d_m3Use32BitSlots + 1)) // need twice as many slots in 32-bit mode @@ -2372,6 +2370,7 @@ M3Result Compile_Function (IM3Function io_function) o->function = io_function; o->wasm = io_function->wasm; o->wasmEnd = io_function->wasmEnd; + o->block.type = funcType; _try { // skip over code size. the end was already calculated during parse phase @@ -2382,23 +2381,28 @@ _ (AcquireCompilationCodePage (o, & o->page)); pc_t pc = GetPagePC (o->page); - // push the arg types to the type stack - o->block.type = ft; + // all args & returns are 64-bit aligned, so use 2 slots for a d_m3Use32BitSlots=1 build + const u32 ioSlotCount = sizeof (u64) / sizeof (m3slot_t); + + u32 numRetSlots = GetFunctionNumReturns (o->function) * ioSlotCount; + + for (u32 i = 0; i < numRetSlots; ++i) + MarkSlotAllocated (o, i); + + o->firstDynamicSlotIndex = numRetSlots; - // all args are 64-bit aligned - const u32 argSlotCount = sizeof (u64) / sizeof (m3slot_t); u32 numArgs = GetFunctionNumArgs (o->function); - u32 numRets = GetFunctionNumReturns(o->function); + // push the arg types to the type stack for (u32 i = 0; i < numArgs; ++i) { - u8 type = ft->types [numRets + i]; + u8 type = GetFunctionArgType (o->function, i); _ (PushAllocatedSlot (o, type)); if (i < numArgs - 1) { // prevent allocator fill-in - o->firstDynamicSlotIndex += argSlotCount; + o->firstDynamicSlotIndex += ioSlotCount; } else { @@ -2407,7 +2411,9 @@ _ (PushAllocatedSlot (o, type)); } } - o->function->numArgSlots = o->firstLocalSlotIndex = o->firstDynamicSlotIndex; + //o->maxAllocatedSlotPlusOne = + o->function->numRetAndArgSlots = o->firstLocalSlotIndex = o->firstDynamicSlotIndex; + _ (CompileLocals (o)); u16 maxSlot = GetMaxUsedSlotPlusOne (o); diff --git a/source/m3_env.c b/source/m3_env.c index b74e9e7..069639d 100644 --- a/source/m3_env.c +++ b/source/m3_env.c @@ -753,6 +753,20 @@ M3ValueType m3_GetRetType (IM3Function i_function, uint32_t index) return c_m3Type_none; } + +u8 * GetStackPointerForArgs (IM3Function i_function) +{ + u64 * stack = (u64 *) i_function->module->runtime->stack; + IM3FuncType ftype = i_function->funcType; + + stack += ftype->numRets; + + printf ("stack: %p (args: %p)\n", i_function->module->runtime->stack, stack); + + return (u8 *) stack; +} + + M3Result m3_CallV (IM3Function i_function, ...) { va_list ap; @@ -775,7 +789,8 @@ M3Result m3_CallVL (IM3Function i_function, va_list i_args) ClearBacktrace (runtime); # endif - u8* s = (u8*) runtime->stack; + u8* s = GetStackPointerForArgs (i_function); + for (u32 i = 0; i < ftype->numArgs; ++i) { switch (d_FuncArgType(ftype, i)) { @@ -815,7 +830,7 @@ M3Result m3_Call (IM3Function i_function, uint32_t i_argc, const void * i_argp ClearBacktrace (runtime); # endif - u8* s = (u8*) runtime->stack; + u8* s = GetStackPointerForArgs (i_function); for (u32 i = 0; i < ftype->numArgs; ++i) { switch (d_FuncArgType(ftype, i)) { @@ -856,7 +871,8 @@ M3Result m3_CallArgv (IM3Function i_function, uint32_t i_argc, const char * i_ ClearBacktrace (runtime); # endif - u8* s = (u8*) runtime->stack; + u8* s = GetStackPointerForArgs (i_function); + for (u32 i = 0; i < ftype->numArgs; ++i) { switch (d_FuncArgType(ftype, i)) { diff --git a/source/m3_exec.h b/source/m3_exec.h index 4195002..befb912 100644 --- a/source/m3_exec.h +++ b/source/m3_exec.h @@ -732,7 +732,7 @@ d_m3Op (Entry) #if defined(DEBUG) function->hits++; #endif - u8 * stack = (u8 *) ((m3slot_t *) _sp + function->numArgSlots); + u8 * stack = (u8 *) ((m3slot_t *) _sp + function->numRetAndArgSlots); memset (stack, 0x0, function->numLocalBytes); stack += function->numLocalBytes; diff --git a/source/m3_function.h b/source/m3_function.h index 8d2681c..d1fa9b3 100644 --- a/source/m3_function.h +++ b/source/m3_function.h @@ -64,7 +64,7 @@ typedef struct M3Function #endif u16 maxStackSlots; - u16 numArgSlots; + u16 numRetAndArgSlots; u16 numLocals; // not including args u16 numLocalBytes; diff --git a/source/m3_info.c b/source/m3_info.c index 6e909a3..193d1d1 100644 --- a/source/m3_info.c +++ b/source/m3_info.c @@ -356,7 +356,7 @@ void dump_type_stack (IM3Compilation o) { if (slot >= o->firstConstSlotIndex) printf ("c"); - else if (slot >= o->function->numArgSlots) + else if (slot >= o->function->numRetAndArgSlots) printf ("L"); else printf ("a");