extensions
Steven Massey 5 years ago
parent 7c5ce6fb2c
commit 61b7e0316d

@ -244,10 +244,13 @@ typedef int64_t (* M3Callback) (IM3Function i_currentFunction, void * i_ref);
// LoadModule transfers ownership of a module to the runtime. Do not free modules once successfully imported into the runtime.
typedef const void * (* M3RawCall) (IM3Runtime runtime, uint64_t * _sp, void * _mem);
M3Result m3_LinkRawFunction (IM3Module io_module,
const char * const i_moduleName,
const char * const i_functionName,
const void * const i_function); // void (u64 * _sp, u8 * _mem)
M3RawCall i_function); // void (u64 * _sp, u8 * _mem)

@ -30,8 +30,6 @@ M3State;
typedef m3ret_t (* M3ArgPusher) (d_m3BindingArgList, M3State * i_state);
typedef f64 (* M3ArgPusherFpReturn) (d_m3BindingArgList, M3State * i_state);
typedef m3ret_t (* M3RawCall) (IM3Runtime runtime, u64 * _sp, void * _mem);
m3ret_t PushArg_runtime (d_m3BindingArgList, M3State * _state)
{
@ -259,9 +257,11 @@ M3Result m3_RegisterFunction (IM3Runtime io_runtime, const char * const i_fun
}
typedef M3Result (* M3Linker) (IM3Module io_module, IM3Function io_function, const char * const i_signature, const void * i_function);
M3Result LinkFunction (IM3Module io_module, IM3Function io_function, const char * const i_signature, const void * i_function)
M3Result LinkCFunction (IM3Module io_module, IM3Function io_function, const char * const i_signature, const void * i_function)
{
M3Result result = c_m3Err_none;
@ -359,11 +359,12 @@ M3Result LinkFunction (IM3Module io_module, IM3Function io_function, const c
}
M3Result m3_LinkCFunction (IM3Module io_module,
const char * const i_moduleName,
const char * const i_functionName,
const char * const i_signature,
const void * i_function)
M3Result FindAndLinkFunction (IM3Module io_module,
ccstr_t i_moduleName,
ccstr_t i_functionName,
ccstr_t i_signature,
voidptr_t i_function,
const M3Linker i_linker)
{
M3Result result = c_m3Err_functionLookupFailed;
@ -376,40 +377,42 @@ M3Result m3_LinkCFunction (IM3Module io_module,
if (strcmp (f->import.fieldUtf8, i_functionName) == 0 and
strcmp (f->import.moduleUtf8, i_moduleName) == 0)
{
result = LinkFunction (io_module, f, i_signature, i_function);
result = i_linker (io_module, f, i_signature, i_function);
}
}
}
return result;
}
// --------------------------------------------------------------------------------------------------------------------------------------------------------------------------
d_m3RetSig CallRawFunction (d_m3OpSig)
M3Result m3_LinkCFunction (IM3Module io_module,
const char * const i_moduleName,
const char * const i_functionName,
const char * const i_signature,
const void * i_function)
{
M3RawCall call = (M3RawCall) (* _pc++);
IM3Runtime runtime = (IM3Runtime) (* _pc++);
m3ret_t possible_trap = call (runtime, _sp, _mem);
return possible_trap;
return FindAndLinkFunction (io_module, i_moduleName, i_functionName, i_signature, i_function, LinkCFunction);
}
M3Result LinkRawFunction (IM3Module io_module, IM3Function io_function, const void * i_function)
// --------------------------------------------------------------------------------------------------------------------------------------------------------------------------
M3Result LinkRawFunction (IM3Module io_module, IM3Function io_function, ccstr_t i_signature, const void * i_function)
{
M3Result result = c_m3Err_none; d_m3Assert (io_module->runtime);
IM3CodePage page = AcquireCodePageWithCapacity (io_module->runtime, 3);
IM3CodePage page = AcquireCodePageWithCapacity (io_module->runtime, 2);
if (page)
{
io_function->compiled = GetPagePC (page);
io_function->module = io_module;
EmitWord (page, CallRawFunction);
EmitWord (page, op_CallRawFunction);
EmitWord (page, i_function);
EmitWord (page, io_module->runtime);
ReleaseCodePage (io_module->runtime, page);
}
@ -419,30 +422,13 @@ M3Result LinkRawFunction (IM3Module io_module, IM3Function io_function, cons
}
M3Result m3_LinkRawFunction (IM3Module io_module,
const char * const i_moduleName,
const char * const i_functionName,
const void * i_function)
M3Result m3_LinkRawFunction (IM3Module io_module,
const char * const i_moduleName,
const char * const i_functionName,
M3RawCall i_function)
{
M3Result result = c_m3Err_functionLookupFailed;
for (u32 i = 0; i < io_module->numFunctions; ++i)
{
IM3Function f = & io_module->functions [i];
if (f->import.moduleUtf8 and f->import.fieldUtf8)
{
if (strcmp (f->import.fieldUtf8, i_functionName) == 0 and
strcmp (f->import.moduleUtf8, i_moduleName) == 0)
{
result = LinkRawFunction (io_module, f, i_function);
}
}
}
return result;
return FindAndLinkFunction (io_module, i_moduleName, i_functionName, NULL, i_function, LinkRawFunction);
}

@ -28,6 +28,7 @@ typedef int8_t i8;
typedef const void * m3ret_t;
typedef const void * voidptr_t;
typedef const char * cstr_t;
typedef const char * const ccstr_t;
typedef const u8 * bytes_t;
@ -140,7 +141,7 @@ typedef struct M3CodePageHeader
M3CodePageHeader;
#define c_m3CodePageFreeLinesThreshold 10
#define c_m3CodePageFreeLinesThreshold 4 // max is probably: select _sss
#define c_m3MemPageSize 65536
#define c_m3MaxFunctionStackHeight d_m3MaxFunctionStackHeight
@ -152,7 +153,6 @@ M3CodePageHeader;
#define c_m3AlignWasmMemoryToPages d_m3AlignWasmMemoryToPages
//#define c_m3MaxSaneWasmSize 1000000000
#define c_m3MaxSaneUtf8Length 2000
#define c_m3MaxNumFunctionArgs d_m3MaxNumFunctionArgs

@ -21,9 +21,10 @@ M3Result EnsureCodePageNumLines (IM3Compilation o, u32 i_numLines)
if (page)
{
d_m3Assert (NumFreeLines (o->page) >= 2);
m3log (emit, "bridging new code page from: %d %p (free slots: %d) to: %d", o->page->info.sequence, GetPC (o), NumFreeLines (o->page), page->info.sequence);
EmitWord (o->page, op_Bridge); d_m3Assert (NumFreeLines (o->page) >= 2);
EmitWord (o->page, op_Bridge);
EmitWord (o->page, GetPagePC (page));
ReleaseCodePage (o->runtime, o->page);
@ -40,21 +41,7 @@ M3Result EnsureCodePageNumLines (IM3Compilation o, u32 i_numLines)
// have execution jump to a new page if slots are critically low
M3Result BridgeToNewPageIfNecessary (IM3Compilation o)
{
return EnsureCodePageNumLines (o, c_m3CodePageFreeLinesThreshold - 2);
}
void log_emit (IM3Compilation o, IM3Operation i_operation)
{
# if DEBUG
OpInfo i = find_operation_info (i_operation);
if (i.info)
{
printf ("%p: %s", GetPC (o), i.info->name);
}
else printf ("not found: %p", i_operation);
# endif
return EnsureCodePageNumLines (o, c_m3CodePageFreeLinesThreshold);
}

@ -219,8 +219,6 @@ typedef struct M3Runtime
M3Memory memory;
M3ErrorInfo error;
}
M3Runtime;

@ -54,9 +54,6 @@ void ReportError2 (IM3Function i_function, m3ret_t i_result)
}
d_m3OpDef (Call)
{
pc_t callPC = immediate (pc_t);
@ -138,6 +135,16 @@ d_m3OpDef (CallIndirect)
}
d_m3OpDef (CallRawFunction)
{
M3RawCall call = (M3RawCall) (* _pc++);
IM3Runtime runtime = GetRuntime (_mem);
m3ret_t possible_trap = call (runtime, _sp, _mem);
return possible_trap;
}
d_m3OpDef (MemCurrent)
{
// TODO: get memory from _mem, so that compiled code isn't tied to a specific runtime
@ -205,7 +212,7 @@ d_m3OpDef (Compile)
d_m3OpDef (Entry)
{
M3MemoryHeader * header = (M3MemoryHeader *) _mem - 1;
M3MemoryHeader * header = GetMemoryHeader (_mem);
if ((void *) _sp <= header->maxStack)
{
@ -242,78 +249,6 @@ d_m3OpDef (Entry)
}
#if d_m3RuntimeStackDumps
d_m3OpDef (DumpStack)
{
u32 opcodeIndex = immediate (u32);
u64 stackHeight = immediate (u64);
IM3Function function = immediate (IM3Function);
cstr_t funcName = (function) ? function->name : "";
printf (" %4d ", opcodeIndex);
printf (" %-25s r0: 0x%016" PRIx64 " i:%" PRIi64 " u:%" PRIu64 "\n", funcName, _r0, _r0, _r0);
printf (" fp0: %lf \n", _fp0);
u64 * sp = _sp;
for (u32 i = 0; i < stackHeight; ++i)
{
printf ("%016llx ", (u64) sp);
cstr_t kind = "";
printf ("%5s %2d: 0x%" PRIx64 " %" PRIi64 "\n", kind, i, (u64) *(sp), (i64) *sp);
++sp;
}
printf ("---------------------------------------------------------------------------------------------------------\n");
return nextOpDirect();
}
#endif
# if d_m3EnableOpProfiling
M3ProfilerSlot s_opProfilerCounts [c_m3ProfilerSlotMask] = {};
void ProfileHit (cstr_t i_operationName)
{
u64 ptr = (u64) i_operationName;
M3ProfilerSlot * slot = & s_opProfilerCounts [ptr & c_m3ProfilerSlotMask];
if (slot->opName)
{
if (slot->opName != i_operationName)
{
printf ("**** profiler slot collision; increase mask width\n");
m3NotImplemented ();
}
}
slot->opName = i_operationName;
slot->hitCount++;
}
# endif
void m3_PrintProfilerInfo ()
{
# if d_m3EnableOpProfiling
for (u32 i = 0; i <= c_m3ProfilerSlotMask; ++i)
{
M3ProfilerSlot * slot = & s_opProfilerCounts [i];
if (slot->opName)
printf ("%13llu %s\n", slot->hitCount, slot->opName);
}
# endif
}
d_m3OpDef (GetGlobal)
{
i64 * global = immediate (i64 *);
@ -412,3 +347,89 @@ d_m3OpDef (BranchTable)
return jumpOp (branches [branchIndex]);
}
d_m3OpDef (CopySlot_64)
{
u64 * dst = slot_ptr (u64);
u64 * src = slot_ptr (u64);
* dst = * src; // printf ("copy: %p <- %" PRIi64 " <- %p\n", dst, * dst, src);
return nextOp ();
}
#if d_m3RuntimeStackDumps
//--------------------------------------------------------------------------------------------------------
d_m3OpDef (DumpStack)
{
u32 opcodeIndex = immediate (u32);
u64 stackHeight = immediate (u64);
IM3Function function = immediate (IM3Function);
cstr_t funcName = (function) ? function->name : "";
printf (" %4d ", opcodeIndex);
printf (" %-25s r0: 0x%016" PRIx64 " i:%" PRIi64 " u:%" PRIu64 "\n", funcName, _r0, _r0, _r0);
printf (" fp0: %lf \n", _fp0);
u64 * sp = _sp;
for (u32 i = 0; i < stackHeight; ++i)
{
printf ("%016llx ", (u64) sp);
cstr_t kind = "";
printf ("%5s %2d: 0x%" PRIx64 " %" PRIi64 "\n", kind, i, (u64) *(sp), (i64) *sp);
++sp;
}
printf ("---------------------------------------------------------------------------------------------------------\n");
return nextOpDirect();
}
#endif
# if d_m3EnableOpProfiling
//--------------------------------------------------------------------------------------------------------
M3ProfilerSlot s_opProfilerCounts [c_m3ProfilerSlotMask] = {};
void ProfileHit (cstr_t i_operationName)
{
u64 ptr = (u64) i_operationName;
M3ProfilerSlot * slot = & s_opProfilerCounts [ptr & c_m3ProfilerSlotMask];
if (slot->opName)
{
if (slot->opName != i_operationName)
{
printf ("**** profiler slot collision; increase mask width\n");
m3NotImplemented ();
}
}
slot->opName = i_operationName;
slot->hitCount++;
}
void m3_PrintProfilerInfo ()
{
for (u32 i = 0; i <= c_m3ProfilerSlotMask; ++i)
{
M3ProfilerSlot * slot = & s_opProfilerCounts [i];
if (slot->opName)
printf ("%13llu %s\n", slot->hitCount, slot->opName);
}
}
# else
void m3_PrintProfilerInfo () {}
# endif

@ -39,14 +39,16 @@
# define constant64(TYPE) * ((TYPE *) _pc++)
#endif
#define nextOpDirect() ((IM3Operation)(* _pc))(_pc + 1, d_m3OpArgs)
#define jumpOpDirect(PC) ((IM3Operation)(* PC))( PC + 1, d_m3OpArgs)
# if d_m3EnableOpProfiling
# define nextOp() profileOp (d_m3OpAllArgs, __PRETTY_FUNCTION__)
d_m3RetSig profileOp (d_m3OpSig, cstr_t i_operationName);
# define nextOp() profileOp (d_m3OpAllArgs, __FUNCTION__)
# elif d_m3TraceExec
# define nextOp() debugOp (d_m3OpAllArgs, __PRETTY_FUNCTION__)
# define nextOp() debugOp (d_m3OpAllArgs, __FUNCTION__)
# else
# define nextOp() nextOpDirect()
# endif
@ -59,44 +61,6 @@ d_m3RetSig Call (d_m3OpSig)
return nextOpDirect();
}
d_m3RetSig debugOp (d_m3OpSig, cstr_t i_opcode)
{
char name [100];
strcpy (name, strstr (i_opcode, "op_") + 3);
char * bracket = strstr (name, "(");
if (bracket) {
*bracket = 0;
}
puts (name);
return nextOpDirect();
}
static const u32 c_m3ProfilerSlotMask = 0xFFFF;
typedef struct M3ProfilerSlot
{
cstr_t opName;
u64 hitCount;
}
M3ProfilerSlot;
void ProfileHit (cstr_t i_operationName);
d_m3RetSig profileOp (d_m3OpSig, cstr_t i_operationName)
{
ProfileHit (i_operationName);
return nextOpDirect();
}
#if d_m3RuntimeStackDumps
d_m3OpDecl (DumpStack)
#endif
// TODO: OK, this needs some explanation here ;0
#define d_m3CommutativeOpMacro(RES, REG, TYPE, NAME, OP, ...) \
@ -615,6 +579,7 @@ d_m3Op (ContinueLoopIf)
d_m3OpDecl (Compile)
d_m3OpDecl (Call)
d_m3OpDecl (CallIndirect)
d_m3OpDecl (CallRawFunction)
d_m3OpDecl (Entry)
d_m3OpDecl (MemCurrent)
@ -676,15 +641,8 @@ d_m3Op (SetGlobal_f64)
}
d_m3Op (CopySlot_64)
{
u64 * dst = slot_ptr (u64);
u64 * src = slot_ptr (u64);
* dst = * src; // printf ("copy: %p <- %" PRIi64 " <- %p\n", dst, * dst, src);
return nextOp ();
}
d_m3OpDecl (CopySlot_64)
d_m3Op (PreserveCopySlot_64)
@ -900,4 +858,48 @@ d_m3Store_i (i64, i64)
# endif
//---------------------------------------------------------------------------------------------------------------------
// debug/profiling
//---------------------------------------------------------------------------------------------------------------------
#if d_m3TraceExec
d_m3RetSig debugOp (d_m3OpSig, cstr_t i_opcode)
{
char name [100];
strcpy (name, strstr (i_opcode, "op_") + 3);
char * bracket = strstr (name, "(");
if (bracket) {
*bracket = 0;
}
puts (name);
return nextOpDirect();
}
# endif
# if d_m3RuntimeStackDumps
d_m3OpDecl (DumpStack)
# endif
# if d_m3EnableOpProfiling
static const u32 c_m3ProfilerSlotMask = 0xFFFF;
typedef struct M3ProfilerSlot
{
cstr_t opName;
u64 hitCount;
}
M3ProfilerSlot;
void ProfileHit (cstr_t i_operationName);
d_m3RetSig profileOp (d_m3OpSig, cstr_t i_operationName)
{
ProfileHit (i_operationName);
return nextOpDirect();
}
# endif
#endif /* m3_exec_h */

@ -403,6 +403,7 @@ void log_opcode (IM3Compilation o, u8 i_opcode)
u16 GetMaxExecSlot (IM3Compilation o);
void emit_stack_dump (IM3Compilation o)
{
# if d_m3RuntimeStackDumps
@ -418,3 +419,17 @@ void emit_stack_dump (IM3Compilation o)
# endif
}
void log_emit (IM3Compilation o, IM3Operation i_operation)
{
# if DEBUG
OpInfo i = find_operation_info (i_operation);
if (i.info)
{
printf ("%p: %s", GetPC (o), i.info->name);
}
else printf ("not found: %p", i_operation);
# endif
}

@ -26,6 +26,7 @@ void dump_type_stack (IM3Compilation o);
void log_opcode (IM3Compilation o, u8 i_opcode);
const char * get_indention_string (IM3Compilation o);
void emit_stack_dump (IM3Compilation o);
void log_emit (IM3Compilation o, IM3Operation i_operation);
#endif /* m3_info_h */

Loading…
Cancel
Save