allow for dynamic callbacks (#86)

extensions
Arnaud Tournier 4 years ago committed by GitHub
parent 89057d8834
commit b280147ec9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -147,3 +147,72 @@ M3Result m3_LinkRawFunction (IM3Module io_module,
{
return FindAndLinkFunction (io_module, i_moduleName, i_functionName, i_signature, (voidptr_t)i_function, LinkRawFunction);
}
// --------------------------------------------------------------------------------------------------------------------------------------------------------------------------
IM3Function FindFunction (IM3Module io_module,
ccstr_t i_moduleName,
ccstr_t i_functionName,
ccstr_t i_signature)
{
M3Result result = m3Err_functionLookupFailed;
bool wildcardModule = (strcmp (i_moduleName, "*") == 0);
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
(wildcardModule or strcmp (f->import.moduleUtf8, i_moduleName) == 0))
{
return f;
}
}
}
return NULL;
}
M3Result LinkRawFunctionEx (IM3Module io_module, IM3Function io_function, ccstr_t signature, const void * i_function, void * cookie)
{
M3Result result = m3Err_none; d_m3Assert (io_module->runtime);
_try {
_ (ValidateSignature (io_function, signature));
IM3CodePage page = AcquireCodePageWithCapacity (io_module->runtime, 3);
if (page)
{
io_function->compiled = GetPagePC (page);
io_function->module = io_module;
EmitWord (page, op_CallRawFunctionEx);
EmitWord (page, i_function);
EmitWord (page, cookie);
ReleaseCodePage (io_module->runtime, page);
}
else _throw(m3Err_mallocFailedCodePage);
} _catch:
return result;
}
M3Result m3_LinkRawFunctionEx (IM3Module io_module,
const char * const i_moduleName,
const char * const i_functionName,
const char * const i_signature,
M3RawCallEx i_function,
void * i_cookie)
{
IM3Function f = FindFunction(io_module, i_moduleName, i_functionName, i_signature);
if (f == NULL)
return m3Err_functionLookupFailed;
M3Result result = LinkRawFunctionEx(io_module, f, i_signature, (voidptr_t)i_function, i_cookie);
return result;
}

@ -120,6 +120,16 @@ d_m3OpDef (CallRawFunction)
return possible_trap;
}
d_m3OpDef (CallRawFunctionEx)
{
M3RawCallEx call = (M3RawCallEx) (* _pc++);
void * cookie = immediate (void *);
IM3Runtime runtime = GetRuntime (_mem);
m3ret_t possible_trap = call (runtime, _sp, m3MemData(_mem), cookie);
return possible_trap;
}
d_m3OpDef (MemCurrent)
{

@ -616,6 +616,7 @@ d_m3OpDecl (Compile)
d_m3OpDecl (Call)
d_m3OpDecl (CallIndirect)
d_m3OpDecl (CallRawFunction)
d_m3OpDecl (CallRawFunctionEx)
d_m3OpDecl (Entry)
d_m3OpDecl (MemCurrent)

@ -208,6 +208,17 @@ d_m3ErrorConst (trapStackOverflow, "[trap] stack overflow")
const char * const i_signature,
M3RawCall i_function);
typedef const void * (* M3RawCallEx) (IM3Runtime runtime, uint64_t * _sp, void * _mem, void * cookie);
// m3_LinkRawFunctionEx links a native callback function that has a cookie parameter, allowing one native
// callback to receive multiple m3 function calls. This ease for dynamic routing in the callback.
M3Result m3_LinkRawFunctionEx (IM3Module io_module,
const char * const i_moduleName,
const char * const i_functionName,
const char * const i_signature,
M3RawCallEx i_function,
void * i_cookie);
//-------------------------------------------------------------------------------------------------------------------------------
// functions
//-------------------------------------------------------------------------------------------------------------------------------

Loading…
Cancel
Save