diff --git a/source/m3_code.c b/source/m3_code.c index c58ef31..d1c23e4 100644 --- a/source/m3_code.c +++ b/source/m3_code.c @@ -21,9 +21,10 @@ IM3CodePage NewCodePage (u32 i_minNumLines) if (page) { - page->info.sequence = ++s_sequence; m3log (code, "new page: %d size: %d", page->info.sequence, pageSize); - - page->info.numLines = (pageSize - sizeof (M3CodePageHeader)) / sizeof (code_t);; + page->info.sequence = ++s_sequence; + page->info.numLines = (pageSize - sizeof (M3CodePageHeader)) / sizeof (code_t); + + m3log (code, "new page: %d; bytes: %d; lines: %d", page->info.sequence, pageSize, page->info.numLines); } return page; diff --git a/source/m3_compile.c b/source/m3_compile.c index d9de733..f9b6ace 100644 --- a/source/m3_compile.c +++ b/source/m3_compile.c @@ -343,7 +343,7 @@ M3Result Push (IM3Compilation o, u8 i_m3Type, i16 i_location) M3Result PushRegister (IM3Compilation o, u8 i_m3Type) { - i16 location = IsFpType (i_m3Type) ? c_m3Fp0SlotAlias : c_m3Reg0SlotAlias; + i16 location = IsFpType (i_m3Type) ? c_m3Fp0SlotAlias : c_m3Reg0SlotAlias; d_m3Assert (i_m3Type); return Push (o, i_m3Type, location); } @@ -1422,6 +1422,9 @@ _ (PreserveRegisterIfOccupied (o, op->type)); if (IsStackTopInRegister (o)) { operation = op->operations [0]; + + if (IsStackTopMinus1InRegister (o)) // for fp.store + operation = op->operations [3]; } else if (IsStackTopMinus1InRegister (o)) { @@ -1493,10 +1496,11 @@ _ (ReadLEB_u32 (& offset, & o->wasm, o->wasmEnd)); m3log (compile, d_indent "%s (offset = %d)", get_indention_string (o), offset); const M3OpInfo * op = & c_operations [i_opcode]; - if (IsFpType (op->type)) + if (IsFpType (op->type)) // loading a float? _ (PreserveRegisterIfOccupied (o, c_m3Type_f64)); _ (Compile_Operator (o, i_opcode)); + EmitConstant (o, offset); _catch: return result; @@ -1507,6 +1511,7 @@ _ (Compile_Operator (o, i_opcode)); #define d_emptyOpList() { NULL, NULL, NULL, NULL } #define d_unaryOpList(TYPE, NAME) { op_##TYPE##_##NAME##_r, op_##TYPE##_##NAME##_s, NULL, NULL } #define d_binOpList(TYPE, NAME) { op_##TYPE##_##NAME##_sr, op_##TYPE##_##NAME##_rs, op_##TYPE##_##NAME##_ss, NULL } +#define d_storeFpOpList(TYPE, NAME) { op_##TYPE##_##NAME##_sr, op_##TYPE##_##NAME##_rs, op_##TYPE##_##NAME##_ss, op_##TYPE##_##NAME##_rr } #define d_commutativeBinOpList(TYPE, NAME) { op_##TYPE##_##NAME##_sr, NULL, op_##TYPE##_##NAME##_ss, NULL } #define d_convertOpList(OP) { op_##OP##_r_r, op_##OP##_r_s, op_##OP##_s_r, op_##OP##_s_s } @@ -1567,8 +1572,8 @@ const M3OpInfo c_operations [] = M3OP( "i32.store", -2, none, d_binOpList (i32, Store_i32), Compile_Load_Store ), // 0x36 M3OP( "i64.store", -2, none, d_binOpList (i64, Store_i64), Compile_Load_Store ), // 0x37 - M3OP( "f32.store", -2, none, d_binOpList (f32, Store_f32), Compile_Load_Store ), // 0x38 - M3OP( "f64.store", -2, none, d_binOpList (f64, Store_f64), Compile_Load_Store ), // 0x39 + M3OP( "f32.store", -2, none, d_storeFpOpList (f32, Store_f32), Compile_Load_Store ), // 0x38 + M3OP( "f64.store", -2, none, d_storeFpOpList (f64, Store_f64), Compile_Load_Store ), // 0x39 M3OP( "i32.store8", -2, none, d_binOpList (i32, Store_u8), Compile_Load_Store ), // 0x3a M3OP( "i32.store16", -2, none, d_binOpList (i32, Store_i16), Compile_Load_Store ), // 0x3b diff --git a/source/m3_core.c b/source/m3_core.c index 66f8916..4a7f26a 100644 --- a/source/m3_core.c +++ b/source/m3_core.c @@ -170,7 +170,12 @@ void m3StackCheck () { char stack; size_t addr = (size_t)&stack; + + size_t stackEnd = stack_end; stack_end = min(stack_end, addr); + +// if (stackEnd != stack_end) +// printf ("maxStack: %ld\n", m3StackGetMax ()); } size_t m3StackGetMax () diff --git a/source/m3_env.c b/source/m3_env.c index eba4614..b74e1b8 100644 --- a/source/m3_env.c +++ b/source/m3_env.c @@ -172,8 +172,9 @@ M3Result EvaluateExpression (IM3Module i_module, void * o_expressed, u8 i_type // create a temporary runtime context M3Runtime rt; - M3_INIT(rt); - + M3_INIT (rt); + + rt.environment = i_module->runtime->environment; rt.numStackSlots = c_m3MaxFunctionStackHeight; rt.stack = & stack; @@ -183,11 +184,12 @@ M3Result EvaluateExpression (IM3Module i_module, void * o_expressed, u8 i_type M3Compilation o = { & rt, i_module, * io_bytes, i_end }; o.block.depth = -1; // so that root compilation depth = 0 - IM3CodePage page = o.page = AcquireCodePage (& rt); + // OPTZ: this code page could be erased after use. maybe have 'empty' list in addition to full and open? + o.page = AcquireCodePage (& rt); // AcquireUnusedCodePage (...) - if (page) + if (o.page) { - pc_t m3code = GetPagePC (page); + pc_t m3code = GetPagePC (o.page); result = CompileBlock (& o, i_type, 0); if (not result) @@ -208,11 +210,12 @@ M3Result EvaluateExpression (IM3Module i_module, void * o_expressed, u8 i_type } } - ReleaseCodePage (& rt, page); + // TODO: EraseCodePage (...) see OPTZ above + ReleaseCodePage (& rt, o.page); } else result = c_m3Err_mallocFailedCodePage; - rt.stack = NULL; // prevent free(stack) in ReleaseRuntime + rt.stack = NULL; // prevent free(stack) in ReleaseRuntime ReleaseRuntime (& rt); i_module->runtime = savedRuntime; @@ -276,7 +279,8 @@ M3Result ResizeMemory (IM3Runtime io_runtime, u32 i_numPages) memory->mallocated->runtime = io_runtime; memory->mallocated->maxStack = (m3reg_t *) io_runtime->stack + io_runtime->numStackSlots * sizeof (m3reg_t) - c_m3MaxFunctionStackHeight; - m3log (runtime, "resized mem: %p; end: %p; pages: %d\n", memory->wasmPages, memory->mallocated->end, memory->numPages); +// printf ("max:stack: %p\n", memory->mallocated->maxStack); + m3log (runtime, "resized mem: %p; end: %p; pages: %d", memory->wasmPages, memory->mallocated->end, memory->numPages); } else result = c_m3Err_mallocFailed; } @@ -437,8 +441,7 @@ M3Result m3_LoadModule (IM3Runtime io_runtime, IM3Module io_module) if (not io_module->runtime) { -// d_m3Assert (io_module->memory.actualSize == 0); - + io_module->runtime = io_runtime; M3Memory * memory = & io_runtime->memory; # if d_m3AllocateLinearMemory @@ -448,15 +451,17 @@ _ (InitGlobals (io_module)); _ (InitDataSegments (memory, io_module)); _ (InitElements (io_module)); - io_module->runtime = io_runtime; io_module->next = io_runtime->modules; io_runtime->modules = io_module; // Functions expect module to be linked to a runtime, so we call start here _ (InitStartFunc (io_module)); } - else _throw (c_m3Err_moduleAlreadyLinked); + else result = c_m3Err_moduleAlreadyLinked; + if (result) + io_module->runtime = NULL; + _catch: return result; } @@ -659,17 +664,23 @@ _ ((M3Result)Call (i_function->compiled, stack, linearMemory, d_m3OpDefaul IM3CodePage AcquireCodePage (IM3Runtime i_runtime) { + IM3CodePage page = NULL; + if (i_runtime->pagesOpen) { - return PopCodePage (& i_runtime->pagesOpen); + page = PopCodePage (& i_runtime->pagesOpen); } else { - if (i_runtime->environment) - i_runtime->environment->numCodePages++; - - return NewCodePage (500); // for 4kB page + page = NewCodePage (500 /* code lines */); // for 4kB page + if (page) + i_runtime->numCodePages++; } + + if (page) + i_runtime->numActiveCodePages++; + + return page; } @@ -689,7 +700,15 @@ IM3CodePage AcquireCodePageWithCapacity (IM3Runtime i_runtime, u32 i_lineCount page = tryAnotherPage; } } - else page = NewCodePage (i_lineCount); + else + { + page = NewCodePage (i_lineCount); + if (page) + i_runtime->numCodePages++; + } + + if (page) + i_runtime->numActiveCodePages++; return page; } @@ -714,6 +733,8 @@ void ReleaseCodePage (IM3Runtime i_runtime, IM3CodePage i_codePage) { if (i_codePage) { +// IM3Environment env = i_runtime->environment; + IM3Runtime env = i_runtime; IM3CodePage * list; if (NumFreeLines (i_codePage) < c_m3CodePageFreeLinesThreshold) @@ -722,15 +743,16 @@ void ReleaseCodePage (IM3Runtime i_runtime, IM3CodePage i_codePage) list = & i_runtime->pagesOpen; PushCodePage (list, i_codePage); - + env->numActiveCodePages--; + # if defined (DEBUG) u32 numOpen = CountPages (i_runtime->pagesOpen); u32 numFull = CountPages (i_runtime->pagesFull); - u32 numTotal = i_runtime->environment ? i_runtime->environment->numCodePages : numFull + numOpen; +// u32 numTotal = env->numCodePages : numFull + numOpen; - m3log (code, "open-pages: %d; full-pages: %d; total: %d", numOpen, numFull, numTotal); + m3log (code, "runtime: %p; open-pages: %d; full-pages: %d; active: %d; total: %d", i_runtime, numOpen, numFull, env->numActiveCodePages, env->numCodePages); -// d_m3Assert (numOpen + numFull == numTotal); + d_m3Assert (numOpen + numFull + env->numActiveCodePages == env->numCodePages); # if d_m3LogCodePages dump_code_page (i_codePage, /* startPC: */ NULL); diff --git a/source/m3_env.h b/source/m3_env.h index 36faefa..6eabbf5 100644 --- a/source/m3_env.h +++ b/source/m3_env.h @@ -187,7 +187,9 @@ IM3Function Module_GetFunction (IM3Module i_module, u32 //--------------------------------------------------------------------------------------------------------------------------------- typedef struct M3Environment { - u32 numCodePages; + u32 dummy; +// u32 numCodePages; +// u32 numActiveCodePages; // u32 numFuncTypes; // M3FuncType * funcTypes; @@ -204,6 +206,9 @@ typedef struct M3Runtime M3CodePage * pagesOpen; // linked list of code pages with writable space on them M3CodePage * pagesFull; // linked list of finalized pages + u32 numCodePages; + u32 numActiveCodePages; + IM3Module modules; // linked list of imported modules void * stack; diff --git a/source/m3_exec.c b/source/m3_exec.c index 5b6b715..aecb48e 100644 --- a/source/m3_exec.c +++ b/source/m3_exec.c @@ -201,12 +201,16 @@ d_m3OpDef (Entry) if (not r) SPrintArg (str, 99, _sp, function->funcType->returnType); - m3log (exec, " exit < %s %s %s %s\n", function->name, returnType ? "->" : "", str, r ? r : ""); + m3log (exec, " exit < %s %s %s %s", function->name, returnType ? "->" : "", str, r ? r : ""); # endif return r; } - else return c_m3Err_trapStackOverflow; + else + { + printf ("stk: %p %p\n", _sp, header->maxStack); + return c_m3Err_trapStackOverflow; + } } diff --git a/source/m3_exec.h b/source/m3_exec.h index 87c9dcf..6e1cd37 100644 --- a/source/m3_exec.h +++ b/source/m3_exec.h @@ -48,7 +48,7 @@ d_m3RetSig Call (d_m3OpSig) { - m3Yield (); +// m3Yield (); return nextOpDirect(); } @@ -853,8 +853,27 @@ d_m3Op (SRC_TYPE##_Store_##DEST_TYPE##_ss) \ else d_outOfBounds; \ } +// both operands can be in regs when storing a float +#define d_m3StoreFp(REG, TYPE) \ +d_m3Op (TYPE##_Store_##TYPE##_rr) \ +{ \ + u32 operand = (u32) _r0; \ + u32 offset = immediate (u32); \ + operand += offset; \ + \ + u8 * end = ((M3MemoryHeader*)(_mem) - 1)->end; \ + u8 * mem8 = (u8 *) (_mem + operand); \ + if (mem8 + sizeof (TYPE) <= end) \ + { \ + * (TYPE *) mem8 = (TYPE) REG; \ + return nextOp (); \ + } \ + else d_outOfBounds; \ +} \ + + #define d_m3Store_i(SRC_TYPE, DEST_TYPE) d_m3Store(_r0, SRC_TYPE, DEST_TYPE) -#define d_m3Store_f(SRC_TYPE, DEST_TYPE) d_m3Store(_fp0, SRC_TYPE, DEST_TYPE) +#define d_m3Store_f(SRC_TYPE, DEST_TYPE) d_m3Store(_fp0, SRC_TYPE, DEST_TYPE) d_m3StoreFp (_fp0, SRC_TYPE); d_m3Store_f (f32, f32) d_m3Store_f (f64, f64) diff --git a/source/m3_info.c b/source/m3_info.c index 6803940..d3871ce 100644 --- a/source/m3_info.c +++ b/source/m3_info.c @@ -154,7 +154,9 @@ OpInfo find_operation_info (IM3Operation i_operation) #undef fetch #define fetch(TYPE) (*(TYPE *) ((*o_pc)++)) -void Decode_Call (char * o_string, u8 i_opcode, IM3OpInfo i_opInfo, pc_t * o_pc) +#define d_m3Decoder(FUNC) void Decode_##FUNC (char * o_string, u8 i_opcode, IM3Operation i_operation, IM3OpInfo i_opInfo, pc_t * o_pc) + +d_m3Decoder (Call) { void * function = fetch (void *); u16 stackOffset = fetch (u16); @@ -163,14 +165,27 @@ void Decode_Call (char * o_string, u8 i_opcode, IM3OpInfo i_opInfo, pc_t * o_p } -void Decode_Entry (char * o_string, u8 i_opcode, IM3OpInfo i_opInfo, pc_t * o_pc) +d_m3Decoder (Entry) { IM3Function function = fetch (IM3Function); sprintf (o_string, "%s", function->name); } -#define d_m3Decoder(FUNC) void Decode_##FUNC (char * o_string, u8 i_opcode, IM3OpInfo i_opInfo, pc_t * o_pc) + +d_m3Decoder (f64_Store) +{ + if (i_operation == i_opInfo->operations [0]) + { + u32 operand = fetch (u32); + u32 offset = fetch (u32); + + sprintf (o_string, "offset= slot:%d + immediate:%d", operand, offset); + } + +// sprintf (o_string, "%s", function->name); +} + d_m3Decoder (Branch) { @@ -178,7 +193,7 @@ d_m3Decoder (Branch) sprintf (o_string, "%p", target); } -void Decode_BranchTable (char * o_string, u8 i_opcode, IM3OpInfo i_opInfo, pc_t * o_pc) +d_m3Decoder (BranchTable) { u16 slot = fetch (u16); @@ -203,7 +218,7 @@ void Decode_BranchTable (char * o_string, u8 i_opcode, IM3OpInfo i_opInfo, pc_ } -void Decode_Const (char * o_string, u8 i_opcode, IM3OpInfo i_opInfo, pc_t * o_pc) +d_m3Decoder (Const) { u64 value = fetch (u64); i32 offset = fetch (i32); sprintf (o_string, " slot [%d] = %" PRIu64, offset, value); @@ -212,9 +227,9 @@ void Decode_Const (char * o_string, u8 i_opcode, IM3OpInfo i_opInfo, pc_t * o_ #undef fetch -void DecodeOperation (char * o_string, u8 i_opcode, IM3OpInfo i_opInfo, pc_t * o_pc) +void DecodeOperation (char * o_string, u8 i_opcode, IM3Operation i_operation, IM3OpInfo i_opInfo, pc_t * o_pc) { - #define d_m3Decode(OPCODE, FUNC) case OPCODE: Decode_##FUNC (o_string, i_opcode, i_opInfo, o_pc); break; + #define d_m3Decode(OPCODE, FUNC) case OPCODE: Decode_##FUNC (o_string, i_opcode, i_operation, i_opInfo, o_pc); break; switch (i_opcode) { @@ -223,6 +238,7 @@ void DecodeOperation (char * o_string, u8 i_opcode, IM3OpInfo i_opInfo, pc_t * d_m3Decode (c_waOp_call, Call) d_m3Decode (c_waOp_branch, Branch) d_m3Decode (c_waOp_branchTable, BranchTable) + d_m3Decode (0x39, f64_Store) } } @@ -244,24 +260,24 @@ void dump_code_page (IM3CodePage i_codePage, pc_t i_startPC) pc_t operationPC = pc; IM3Operation op = (IM3Operation) (* pc++); - if (op) - { OpInfo i = find_operation_info (op); if (i.info) { char infoString [1000] = { 0 }; - DecodeOperation (infoString, i.opcode, i.info, & pc); + DecodeOperation (infoString, i.opcode, op, i.info, & pc); m3log (code, "%p | %20s %s", operationPC, i.info->name, infoString); } -// else break; - } -// else break; + else + m3log (code, "%p | %p", operationPC, op); + } m3log (code, "---------------------------------------------------------------------------------------"); + + m3log (code, "free-lines: %d", i_codePage->info.numLines - i_codePage->info.lineIndex); } # endif @@ -381,6 +397,12 @@ void log_opcode (IM3Compilation o, u8 i_opcode) m3log (compile, "%4d | 0x%02x %s", o->numOpcodes++, i_opcode, GetOpcodeIndentionString (o)); # endif + if (o->numOpcodes == 1198) + { + if (strncmp (o->function->name, "rad", 3) == 0) + printf ("hmmm...\n"); + } + if (i_opcode == c_waOp_end or i_opcode == c_waOp_else) o->block.depth++; }