InjectFunction functional

extensions
Steven Massey 3 years ago
parent 3400422896
commit 320e04a704

@ -12,7 +12,7 @@
#include "m3_exception.h"
IM3Module w3_NewModule (IM3Environment i_environment)
IM3Module m3_NewModule (IM3Environment i_environment)
{
IM3Module module = m3_AllocStruct (M3Module);
@ -31,22 +31,27 @@ IM3Module w3_NewModule (IM3Environment i_environment)
M3Result w3_InjectFunction (IM3Module i_module,
M3Result m3_InjectFunction (IM3Module i_module,
int32_t * io_functionIndex,
const char * const i_signature,
const uint8_t * const i_wasmBytes,
uint32_t i_numWasmBytes,
bool i_doCompilation)
{
M3Result result = m3Err_none; d_m3Assert (io_functionIndex);
IM3Function function = NULL;
IM3FuncType ftype = NULL;
_ (SignatureToFuncType (& ftype, i_signature));
i32 index = * io_functionIndex;
IM3FuncType ftype;
_ (SignatureToFuncType (& ftype, i_signature));
IM3Function function = NULL;
bytes_t bytes = i_wasmBytes;
bytes_t end = i_wasmBytes + 5;
u32 size;
_ (ReadLEB_u32 (& size, & bytes, end));
end = bytes + size;
if (index >= 0)
{
_throwif ("function index out of bounds", index >= i_module->numFunctions);
@ -75,16 +80,17 @@ _ (Module_AddFunction (i_module, funcTypeIndex, NULL));
* io_functionIndex = index;
}
function->compiled = NULL;
if (function->ownsWasmCode)
m3_Free (function->wasm);
function->wasm = m3_CopyMem (i_wasmBytes, i_numWasmBytes);
size_t numBytes = end - i_wasmBytes;
function->wasm = m3_CopyMem (i_wasmBytes, numBytes);
_throwifnull (function->wasm);
function->wasmEnd = function->wasm + i_numWasmBytes;
function->wasmEnd = function->wasm + numBytes;
function->ownsWasmCode = true;
function->compiled = NULL;
if (i_doCompilation and not i_module->runtime)
_throw ("module must be loaded into runtime to compile function");

@ -23,17 +23,16 @@ extern "C" {
//-------------------------------------------------------------------------------------------------------------------------------
// Creates an empty module.
IM3Module w3_NewModule (IM3Environment i_environment);
IM3Module m3_NewModule (IM3Environment i_environment);
// To append a new function, set io_functionIndex to negative. On return, the new function index will be set.
// To overwrite an existing function, set io_functionIndex to the desired element. i_signature must match the existing
// function signature.
M3Result w3_InjectFunction (IM3Module i_module,
// function signature. ** InjectFunction invalidates any IM3Function pointers held by the client.
M3Result m3_InjectFunction (IM3Module i_module,
int32_t * io_functionIndex,
const char * const i_signature,
const uint8_t * const i_wasmBytes, // i_wasmBytes is copied
uint32_t i_numWasmBytes,
bool i_doCompilation);

@ -2341,8 +2341,9 @@ M3Result Compile_Function (IM3Function io_function)
{
IM3FuncType ft = 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)]);
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)]);
IM3Runtime runtime = io_function->module->runtime;
IM3Compilation o = & runtime->compilation;
@ -2355,6 +2356,10 @@ M3Result Compile_Function (IM3Function io_function)
o->wasmEnd = io_function->wasmEnd;
_try {
// skip over code size. the end was already calculated during parse phase
u32 size;
_ (ReadLEB_u32 (& size, & o->wasm, o->wasmEnd)); d_m3Assert (size == (o->wasmEnd - o->wasm))
_ (AcquireCompilationCodePage (o, & o->page));
pc_t pc = GetPagePC (o->page);

@ -16,7 +16,7 @@
M3Result AllocFuncType (IM3FuncType * o_functionType, u32 i_numTypes)
{
*o_functionType = (IM3FuncType)m3_Malloc (sizeof (M3FuncType) + i_numTypes);
*o_functionType = (IM3FuncType) m3_Malloc (sizeof (M3FuncType) + i_numTypes);
return (*o_functionType) ? m3Err_none : m3Err_mallocFailed;
}
@ -186,7 +186,7 @@ IM3Environment m3_NewEnvironment ()
_try
{
// create FuncTypes for all simple block return ValueTypes
for (int t = c_m3Type_none; t <= c_m3Type_f64; t++)
for (u8 t = c_m3Type_none; t <= c_m3Type_f64; t++)
{
IM3FuncType ftype;
_ (AllocFuncType (& ftype, 1));

@ -149,10 +149,10 @@ typedef struct M3Module
cstr_t name;
u32 numFuncTypes;
IM3FuncType * funcTypes; // array of pointers to list of FuncTypes
IM3FuncType * funcTypes; // array of pointers to list of FuncTypes
u32 numImports;
//IM3Function * imports; b // notice: "I" prefix. imports are pointers to functions in another module.
//IM3Function * imports; b // notice: "I" prefix. imports are pointers to functions in another module.
u32 numFunctions;
M3Function * functions;
@ -195,8 +195,8 @@ typedef struct M3Environment
IM3FuncType funcTypes; // linked list
IM3FuncType retFuncTypes [c_m3Type_unknown]; // the number of elements must match the basic types as per M3ValueType
IM3FuncType retFuncTypes [c_m3Type_unknown]; // these 'point' to elements in the linked list above.
// the number of elements must match the basic types as per M3ValueType
M3CodePage * pagesReleased;
}
M3Environment;

@ -87,8 +87,8 @@ _try {
func->numNames = 1;
func->names[0] = i_importInfo->fieldUtf8;
}
// m3log (module, " added function: %3d; sig: %d", index, i_typeIndex);
m3log (module, " added function: %3d; sig: %d", index, i_typeIndex);
} _catch:
return result;

@ -314,6 +314,8 @@ _ (ReadLEB_u32 (& numFunctions, & i_bytes, i_end));
for (u32 f = 0; f < numFunctions; ++f)
{
const u8 * start = i_bytes;
u32 size;
_ (ReadLEB_u32 (& size, & i_bytes, i_end));
@ -324,8 +326,6 @@ _ (ReadLEB_u32 (& size, & i_bytes, i_end));
if (i_bytes <= i_end)
{
const u8 * start = ptr;
u32 numLocalBlocks;
_ (ReadLEB_u32 (& numLocalBlocks, & ptr, i_end)); m3log (parse, " code size: %-4d", size);
@ -348,7 +348,7 @@ _ (NormalizeType (& normalType, wasmType));
func->module = io_module;
func->wasm = start;
func->wasmEnd = i_bytes;
func->wasmEnd = i_bytes;
//func->ownsWasmCode = io_module->hasWasmCodeCopy;
func->numLocals = numLocals;
}

@ -132,24 +132,31 @@ int main (int i_argc, const char * i_argv [])
IM3Runtime runtime = m3_NewRuntime (env, 1024, NULL);
IM3Module module = w3_NewModule (env);
IM3Module module = m3_NewModule (env);
i32 functionIndex = -1;
u8 wasm [2] = { 0x00, 0x0b };
u8 wasm [5] = { 0x04, // size
0x00, // num local defs
0x41, 0x37, // i32.const= 55
0x0b // end block
};
// will partially fail (compilation) because module isn't attached to a runtime yet.
result = w3_InjectFunction (module, & functionIndex, "f()", wasm, 2, true); expect (result != m3Err_none)
result = m3_InjectFunction (module, & functionIndex, "i()", wasm, true); expect (result != m3Err_none)
expect (functionIndex >= 0)
result = m3_LoadModule (runtime, module); expect (result == m3Err_none)
result = w3_InjectFunction (module, & functionIndex, "f()", wasm, 2, true); expect (result == m3Err_none)
printf ("%s\n", result);
result = m3_InjectFunction (module, & functionIndex, "i()", wasm, true); expect (result == m3Err_none)
// IM3Function function = w3_GetFunctionByIndex (module, functionIndex);
// m3_FindFunction (<#IM3Function *o_function#>, IM3Runtime i_runtime, <#const char *const i_functionName#>)
// printf ("%s\n", result);
m3_FreeRuntime (runtime);
}

Loading…
Cancel
Save