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. // 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, M3Result m3_LinkRawFunction (IM3Module io_module,
const char * const i_moduleName, const char * const i_moduleName,
const char * const i_functionName, 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 m3ret_t (* M3ArgPusher) (d_m3BindingArgList, M3State * i_state);
typedef f64 (* M3ArgPusherFpReturn) (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) 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; 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, M3Result FindAndLinkFunction (IM3Module io_module,
const char * const i_moduleName, ccstr_t i_moduleName,
const char * const i_functionName, ccstr_t i_functionName,
const char * const i_signature, ccstr_t i_signature,
const void * i_function) voidptr_t i_function,
const M3Linker i_linker)
{ {
M3Result result = c_m3Err_functionLookupFailed; M3Result result = c_m3Err_functionLookupFailed;
@ -376,40 +377,42 @@ M3Result m3_LinkCFunction (IM3Module io_module,
if (strcmp (f->import.fieldUtf8, i_functionName) == 0 and if (strcmp (f->import.fieldUtf8, i_functionName) == 0 and
strcmp (f->import.moduleUtf8, i_moduleName) == 0) 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; 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++); return FindAndLinkFunction (io_module, i_moduleName, i_functionName, i_signature, i_function, LinkCFunction);
IM3Runtime runtime = (IM3Runtime) (* _pc++);
m3ret_t possible_trap = call (runtime, _sp, _mem);
return possible_trap;
} }
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); 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) if (page)
{ {
io_function->compiled = GetPagePC (page); io_function->compiled = GetPagePC (page);
io_function->module = io_module; io_function->module = io_module;
EmitWord (page, CallRawFunction); EmitWord (page, op_CallRawFunction);
EmitWord (page, i_function); EmitWord (page, i_function);
EmitWord (page, io_module->runtime);
ReleaseCodePage (io_module->runtime, page); ReleaseCodePage (io_module->runtime, page);
} }
@ -419,30 +422,13 @@ M3Result LinkRawFunction (IM3Module io_module, IM3Function io_function, cons
} }
M3Result m3_LinkRawFunction (IM3Module io_module, M3Result m3_LinkRawFunction (IM3Module io_module,
const char * const i_moduleName, const char * const i_moduleName,
const char * const i_functionName, const char * const i_functionName,
const void * i_function) M3RawCall i_function)
{ {
M3Result result = c_m3Err_functionLookupFailed; return FindAndLinkFunction (io_module, i_moduleName, i_functionName, NULL, i_function, LinkRawFunction);
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;
} }

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

@ -21,9 +21,10 @@ M3Result EnsureCodePageNumLines (IM3Compilation o, u32 i_numLines)
if (page) 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); 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)); EmitWord (o->page, GetPagePC (page));
ReleaseCodePage (o->runtime, o->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 // have execution jump to a new page if slots are critically low
M3Result BridgeToNewPageIfNecessary (IM3Compilation o) M3Result BridgeToNewPageIfNecessary (IM3Compilation o)
{ {
return EnsureCodePageNumLines (o, c_m3CodePageFreeLinesThreshold - 2); return EnsureCodePageNumLines (o, c_m3CodePageFreeLinesThreshold);
}
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
} }

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

@ -54,9 +54,6 @@ void ReportError2 (IM3Function i_function, m3ret_t i_result)
} }
d_m3OpDef (Call) d_m3OpDef (Call)
{ {
pc_t callPC = immediate (pc_t); 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) d_m3OpDef (MemCurrent)
{ {
// TODO: get memory from _mem, so that compiled code isn't tied to a specific runtime // 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) d_m3OpDef (Entry)
{ {
M3MemoryHeader * header = (M3MemoryHeader *) _mem - 1; M3MemoryHeader * header = GetMemoryHeader (_mem);
if ((void *) _sp <= header->maxStack) 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) d_m3OpDef (GetGlobal)
{ {
i64 * global = immediate (i64 *); i64 * global = immediate (i64 *);
@ -412,3 +347,89 @@ d_m3OpDef (BranchTable)
return jumpOp (branches [branchIndex]); 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++) # define constant64(TYPE) * ((TYPE *) _pc++)
#endif #endif
#define nextOpDirect() ((IM3Operation)(* _pc))(_pc + 1, d_m3OpArgs) #define nextOpDirect() ((IM3Operation)(* _pc))(_pc + 1, d_m3OpArgs)
#define jumpOpDirect(PC) ((IM3Operation)(* PC))( PC + 1, d_m3OpArgs) #define jumpOpDirect(PC) ((IM3Operation)(* PC))( PC + 1, d_m3OpArgs)
# if d_m3EnableOpProfiling # 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 # elif d_m3TraceExec
# define nextOp() debugOp (d_m3OpAllArgs, __PRETTY_FUNCTION__) # define nextOp() debugOp (d_m3OpAllArgs, __FUNCTION__)
# else # else
# define nextOp() nextOpDirect() # define nextOp() nextOpDirect()
# endif # endif
@ -59,44 +61,6 @@ d_m3RetSig Call (d_m3OpSig)
return nextOpDirect(); 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 // TODO: OK, this needs some explanation here ;0
#define d_m3CommutativeOpMacro(RES, REG, TYPE, NAME, OP, ...) \ #define d_m3CommutativeOpMacro(RES, REG, TYPE, NAME, OP, ...) \
@ -615,6 +579,7 @@ d_m3Op (ContinueLoopIf)
d_m3OpDecl (Compile) d_m3OpDecl (Compile)
d_m3OpDecl (Call) d_m3OpDecl (Call)
d_m3OpDecl (CallIndirect) d_m3OpDecl (CallIndirect)
d_m3OpDecl (CallRawFunction)
d_m3OpDecl (Entry) d_m3OpDecl (Entry)
d_m3OpDecl (MemCurrent) 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) d_m3Op (PreserveCopySlot_64)
@ -900,4 +858,48 @@ d_m3Store_i (i64, i64)
# endif # 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 */ #endif /* m3_exec_h */

@ -403,6 +403,7 @@ void log_opcode (IM3Compilation o, u8 i_opcode)
u16 GetMaxExecSlot (IM3Compilation o); u16 GetMaxExecSlot (IM3Compilation o);
void emit_stack_dump (IM3Compilation o) void emit_stack_dump (IM3Compilation o)
{ {
# if d_m3RuntimeStackDumps # if d_m3RuntimeStackDumps
@ -418,3 +419,17 @@ void emit_stack_dump (IM3Compilation o)
# endif # 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); void log_opcode (IM3Compilation o, u8 i_opcode);
const char * get_indention_string (IM3Compilation o); const char * get_indention_string (IM3Compilation o);
void emit_stack_dump (IM3Compilation o); void emit_stack_dump (IM3Compilation o);
void log_emit (IM3Compilation o, IM3Operation i_operation);
#endif /* m3_info_h */ #endif /* m3_info_h */

Loading…
Cancel
Save