Skip to content

Commit

Permalink
Update to 0.4.7
Browse files Browse the repository at this point in the history
  • Loading branch information
vshymanskyy committed May 1, 2020
1 parent dd13d3f commit d43f26e
Show file tree
Hide file tree
Showing 27 changed files with 1,925 additions and 1,212 deletions.
16 changes: 16 additions & 0 deletions src/m3_api_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,20 @@
#define m3ApiTrap(VALUE) { return VALUE; }
#define m3ApiSuccess() { return m3Err_none; }

# if defined(M3_BIG_ENDIAN)
# define m3ApiReadMem16(ptr) __builtin_bswap16((* (u16 *)(ptr)))
# define m3ApiReadMem32(ptr) __builtin_bswap32((* (u32 *)(ptr)))
# define m3ApiReadMem64(ptr) __builtin_bswap64((* (u64 *)(ptr)))
# define m3ApiWriteMem16(ptr, val) { * (u16 *)(ptr) = __builtin_bswap16((val)); }
# define m3ApiWriteMem32(ptr, val) { * (u32 *)(ptr) = __builtin_bswap32((val)); }
# define m3ApiWriteMem64(ptr, val) { * (u64 *)(ptr) = __builtin_bswap64((val)); }
# else
# define m3ApiReadMem16(ptr) (* (u16 *)(ptr))
# define m3ApiReadMem32(ptr) (* (u32 *)(ptr))
# define m3ApiReadMem64(ptr) (* (u64 *)(ptr))
# define m3ApiWriteMem16(ptr, val) { * (u16 *)(ptr) = (val); }
# define m3ApiWriteMem32(ptr, val) { * (u32 *)(ptr) = (val); }
# define m3ApiWriteMem64(ptr, val) { * (u64 *)(ptr) = (val); }
# endif

#endif // m3_api_defs_h
4 changes: 2 additions & 2 deletions src/m3_api_libc.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ M3Result SuppressLookupFailure (M3Result i_result)

m3ApiRawFunction(m3_spectest_dummy)
{
return m3Err_none;
m3ApiSuccess();
}

m3ApiRawFunction(m3_wasm3_raw_sum)
Expand All @@ -87,7 +87,7 @@ m3ApiRawFunction(m3_wasm3_raw_sum)

m3ApiReturn(val1 + val2 + val3 + val4);

return m3Err_none;
m3ApiSuccess();
}

/* TODO: implement direct native function calls (using libffi?)
Expand Down
8 changes: 2 additions & 6 deletions src/m3_api_libc.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,11 @@

#include "m3_core.h"

#if defined(__cplusplus)
extern "C" {
#endif
d_m3BeginExternC

M3Result m3_LinkLibC (IM3Module io_module);
M3Result m3_LinkSpecTest (IM3Module io_module);

#if defined(__cplusplus)
}
#endif
d_m3EndExternC

#endif // m3_api_libc_h
174 changes: 150 additions & 24 deletions src/m3_bind.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@
#include "m3_exec.h"
#include "m3_env.h"
#include "m3_exception.h"
#include "m3_info.h"


static
u8 ConvertTypeCharToTypeId (char i_code)
{
switch (i_code) {
Expand All @@ -23,28 +24,40 @@ u8 ConvertTypeCharToTypeId (char i_code)
return c_m3Type_none;
}

static
M3Result ValidateSignature (IM3Function i_function, ccstr_t i_linkingSignature)

M3Result SignatureToFuncType (IM3FuncType * o_functionType, ccstr_t i_signature)
{
M3Result result = m3Err_none;

cstr_t sig = i_linkingSignature;
IM3FuncType funcType = NULL;
_try {
if (not o_functionType)
_throw ("null function type");

if (not i_signature)
_throw ("null function signature");

cstr_t sig = i_signature;

bool hasReturn = false;
u32 numArgs = 0;

size_t maxNumArgs = strlen (i_signature);
_throwif (m3Err_malformedFunctionSignature, maxNumArgs < 3);

maxNumArgs -= 3; // "v()"
_throwif ("insane argument count", maxNumArgs > d_m3MaxSaneFunctionArgCount);

_ (AllocFuncType (& funcType, (u32) maxNumArgs));

bool parsingArgs = false;
while (* sig)
{
if (numArgs >= d_m3MaxNumFunctionArgs)
_throw ("arg count overflow");

char typeChar = * sig++;

if (typeChar == '(')
{
if (not hasReturn)
_throw ("malformed function signature; missing return type");
break;

parsingArgs = true;
continue;
Expand All @@ -56,30 +69,76 @@ M3Result ValidateSignature (IM3Function i_function, ccstr_t i_linkingSignature

u8 type = ConvertTypeCharToTypeId (typeChar);

if (type)
if (not type)
_throw ("unknown argument type char");

if (not parsingArgs)
{
if (not parsingArgs)
{
if (hasReturn)
_throw ("malformed function signature; too many return types");
if (hasReturn)
_throw ("malformed function signature; too many return types");

hasReturn = true;
}
else
hasReturn = true;

// M3FuncType doesn't speak 'void'
if (type == c_m3Type_void)
type = c_m3Type_none;
if (type == c_m3Type_ptr)
type = c_m3Type_i32;

funcType->returnType = type;
}
else
{
_throwif (m3Err_malformedFunctionSignature, funcType->numArgs >= maxNumArgs); // forgot trailing ')' ?

if (type != c_m3Type_runtime)
{
if (type != c_m3Type_runtime)
++numArgs;
if (type == c_m3Type_ptr)
type = c_m3Type_i32;

funcType->argTypes [funcType->numArgs++] = type;
}
}
else _throw ("unknown argument type char");
}

if (GetFunctionNumArgs (i_function) != numArgs)
_throw ("function arg count mismatch");
if (not hasReturn)
_throw (m3Err_funcSignatureMissingReturnType);

} _catch:

if (result)
m3Free (funcType); // nulls funcType

* o_functionType = funcType;

return result;
}


static
M3Result ValidateSignature (IM3Function i_function, ccstr_t i_linkingSignature)
{
M3Result result = m3Err_none;

IM3FuncType ftype = NULL;
_ (SignatureToFuncType (& ftype, i_linkingSignature));

if (not AreFuncTypesEqual (ftype, i_function->funcType))
{
m3log (module, "expected: %s", SPrintFuncTypeSignature (ftype));
m3log (module, " found: %s", SPrintFuncTypeSignature (i_function->funcType));

_throw ("function signature mismatch");
}

_catch:

m3Free (ftype);

_catch: return result;
return result;
}


typedef M3Result (* M3Linker) (IM3Module io_module, IM3Function io_function, const char * const i_signature, const void * i_function);

M3Result FindAndLinkFunction (IM3Module io_module,
Expand All @@ -92,7 +151,7 @@ M3Result FindAndLinkFunction (IM3Module io_module,
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];
Expand Down Expand Up @@ -147,3 +206,70 @@ 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)
{
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;
}
73 changes: 61 additions & 12 deletions src/m3_code.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,34 @@ IM3CodePage NewCodePage (u32 i_minNumLines)
u32 pageSize = sizeof (M3CodePageHeader) + sizeof (code_t) * i_minNumLines;

pageSize = (pageSize + (d_m3CodePageAlignSize-1)) & ~(d_m3CodePageAlignSize-1); // align
m3Malloc ((void **) & page, pageSize);
m3Alloc ((void **) & page, u8, pageSize);

if (page)
{
page->info.sequence = ++s_sequence;
page->info.numLines = (pageSize - sizeof (M3CodePageHeader)) / sizeof (code_t);

m3log (emit, "new page: %p; seq: %d; bytes: %d; lines: %d", GetPagePC (page), page->info.sequence, pageSize, page->info.numLines);
m3log (runtime, "new page: %p; seq: %d; bytes: %d; lines: %d", GetPagePC (page), page->info.sequence, pageSize, page->info.numLines);
}

return page;
}


void FreeCodePages (IM3CodePage i_page)
void FreeCodePages (IM3CodePage * io_list)
{
while (i_page)
IM3CodePage page = * io_list;

while (page)
{
m3log (code, "free page: %d util: %3.1f%%", i_page->info.sequence, 100. * i_page->info.lineIndex / i_page->info.numLines);
m3log (code, "free page: %d; %p; util: %3.1f%%", page->info.sequence, page, 100. * page->info.lineIndex / page->info.numLines);

IM3CodePage next = i_page->info.next;
m3Free (i_page);
i_page = next;
IM3CodePage next = page->info.next;
m3Free (page);
page = next;
}

* io_list = NULL;
}


Expand All @@ -53,13 +57,25 @@ u32 NumFreeLines (IM3CodePage i_page)

void EmitWord_impl (IM3CodePage i_page, void * i_word)
{ d_m3Assert (i_page->info.lineIndex+1 <= i_page->info.numLines);
i_page->code [i_page->info.lineIndex++] = (void *) i_word;
i_page->code [i_page->info.lineIndex++] = i_word;
}

void EmitWord32 (IM3CodePage i_page, const u32 i_word)
{ d_m3Assert (i_page->info.lineIndex+1 <= i_page->info.numLines);
* ((u32 *) & i_page->code [i_page->info.lineIndex++]) = i_word;
}

void EmitWord64_impl (IM3CodePage i_page, const u64 i_word)
{ d_m3Assert (i_page->info.lineIndex+2 <= i_page->info.numLines);
*((u64 *) & i_page->code [i_page->info.lineIndex]) = i_word;
void EmitWord64 (IM3CodePage i_page, const u64 i_word)
{
#if M3_SIZEOF_PTR == 4
d_m3Assert (i_page->info.lineIndex+2 <= i_page->info.numLines);
* ((u64 *) & i_page->code [i_page->info.lineIndex]) = i_word;
i_page->info.lineIndex += 2;
#else
d_m3Assert (i_page->info.lineIndex+1 <= i_page->info.numLines);
* ((u64 *) & i_page->code [i_page->info.lineIndex]) = i_word;
i_page->info.lineIndex += 1;
#endif
}


Expand Down Expand Up @@ -94,3 +110,36 @@ IM3CodePage PopCodePage (IM3CodePage * i_list)

return page;
}



u32 FindCodePageEnd (IM3CodePage i_list, IM3CodePage * o_end)
{
u32 numPages = 0;
* o_end = NULL;

while (i_list)
{
* o_end = i_list;
++numPages;
i_list = i_list->info.next;
}

return numPages;
}


u32 CountCodePages (IM3CodePage i_list)
{
IM3CodePage unused;
return FindCodePageEnd (i_list, & unused);
}


IM3CodePage GetEndCodePage (IM3CodePage i_list)
{
IM3CodePage end;
FindCodePageEnd (i_list, & end);

return end;
}
Loading

0 comments on commit d43f26e

Please sign in to comment.