Skip to content

Commit

Permalink
Update to v0.4.9
Browse files Browse the repository at this point in the history
  • Loading branch information
vshymanskyy committed Mar 12, 2021
1 parent f634d5d commit 0821f8a
Show file tree
Hide file tree
Showing 24 changed files with 1,375 additions and 858 deletions.
8 changes: 7 additions & 1 deletion src/m3_api_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,13 @@
#define m3ApiGetArg(TYPE, NAME) TYPE NAME = * ((TYPE *) (_sp++));
#define m3ApiGetArgMem(TYPE, NAME) TYPE NAME = (TYPE)m3ApiOffsetToPtr(* ((u32 *) (_sp++)));

#define m3ApiRawFunction(NAME) const void * NAME (IM3Runtime runtime, uint64_t * _sp, void * _mem, void * userdata)
#if d_m3SkipMemoryBoundsCheck
# define m3ApiCheckMem(off, len)
#else
# define m3ApiCheckMem(off, len) { if (UNLIKELY(off == _mem || ((u64)(off) + (len)) > ((u64)(_mem)+runtime->memory.mallocated->length))) m3ApiTrap(m3Err_trapOutOfBoundsMemoryAccess); }
#endif

#define m3ApiRawFunction(NAME) const void * NAME (IM3Runtime runtime, IM3ImportContext _ctx, uint64_t * _sp, void * _mem)
#define m3ApiReturn(VALUE) { *raw_return = (VALUE); return m3Err_none; }
#define m3ApiTrap(VALUE) { return VALUE; }
#define m3ApiSuccess() { return m3Err_none; }
Expand Down
53 changes: 24 additions & 29 deletions src/m3_api_libc.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ m3ApiRawFunction(m3_libc_memset)
m3ApiGetArg (int32_t, i_value)
m3ApiGetArg (int32_t, i_size)

m3ApiCheckMem(i_ptr, i_size);

u32 result = m3ApiPtrToOffset(memset (i_ptr, i_value, i_size));
m3ApiReturn(result);
}
Expand All @@ -51,15 +53,33 @@ m3ApiRawFunction(m3_libc_memmove)
m3ApiGetArgMem (void*, i_src)
m3ApiGetArg (int32_t, i_size)

m3ApiCheckMem(o_dst, i_size);
m3ApiCheckMem(i_src, i_size);

u32 result = m3ApiPtrToOffset(memmove (o_dst, i_src, i_size));
m3ApiReturn(result);
}

m3ApiRawFunction(m3_libc_clock)
m3ApiRawFunction(m3_libc_print)
{
m3ApiReturnType (uint32_t)

m3ApiReturn(clock());
m3ApiGetArgMem (void*, i_ptr)
m3ApiGetArg (uint32_t, i_size)

m3ApiCheckMem(i_ptr, i_size);

fwrite(i_ptr, i_size, 1, stdout);
fflush(stdout);

m3ApiReturn(i_size);
}

m3ApiRawFunction(m3_libc_clock_ms)
{
m3ApiReturnType (uint32_t)

m3ApiReturn(clock() / (CLOCKS_PER_SEC/1000));
}

static
Expand All @@ -76,33 +96,11 @@ m3ApiRawFunction(m3_spectest_dummy)
m3ApiSuccess();
}

m3ApiRawFunction(m3_wasm3_raw_sum)
{
m3ApiReturnType (int64_t)
m3ApiGetArg (int32_t, val1)
m3ApiGetArg (int32_t, val2)
m3ApiGetArg (int32_t, val3)
m3ApiGetArg (int32_t, val4)

m3ApiReturn(val1 + val2 + val3 + val4);

m3ApiSuccess();
}

/* TODO: implement direct native function calls (using libffi?)
i64 m3_wasm3_native_sum(i32 val1, i32 val2, i32 val3, i32 val4)
{
return val1 + val2 + val3 + val4;
}
*/


M3Result m3_LinkSpecTest (IM3Module module)
{
M3Result result = m3Err_none;

const char* spectest = "spectest";
const char* wasm3 = "wasm3";

_ (SuppressLookupFailure (m3_LinkRawFunction (module, spectest, "print", "v()", &m3_spectest_dummy)));
_ (SuppressLookupFailure (m3_LinkRawFunction (module, spectest, "print_i32", "v(i)", &m3_spectest_dummy)));
Expand All @@ -112,10 +110,6 @@ _ (SuppressLookupFailure (m3_LinkRawFunction (module, spectest, "print_f64",
_ (SuppressLookupFailure (m3_LinkRawFunction (module, spectest, "print_i32_f32", "v(if)", &m3_spectest_dummy)));
_ (SuppressLookupFailure (m3_LinkRawFunction (module, spectest, "print_i64_f64", "v(IF)", &m3_spectest_dummy)));


_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasm3, "raw_sum", "I(iiii)", &m3_wasm3_raw_sum)));
//_ (SuppressLookupFailure (m3_LinkCFunction (module, wasm3, "native_sum", "I(iiii)", &m3_wasm3_native_sum)));

_catch:
return result;
}
Expand All @@ -127,12 +121,13 @@ M3Result m3_LinkLibC (IM3Module module)

const char* env = "env";

_ (SuppressLookupFailure (m3_LinkRawFunction (module, env, "_debug", "i(*i)", &m3_libc_print)));
_ (SuppressLookupFailure (m3_LinkRawFunction (module, env, "_memset", "*(*ii)", &m3_libc_memset)));
_ (SuppressLookupFailure (m3_LinkRawFunction (module, env, "_memmove", "*(**i)", &m3_libc_memmove)));
_ (SuppressLookupFailure (m3_LinkRawFunction (module, env, "_memcpy", "*(**i)", &m3_libc_memmove))); // just alias of memmove
_ (SuppressLookupFailure (m3_LinkRawFunction (module, env, "_abort", "v()", &m3_libc_abort)));
_ (SuppressLookupFailure (m3_LinkRawFunction (module, env, "_exit", "v(i)", &m3_libc_exit)));
_ (SuppressLookupFailure (m3_LinkRawFunction (module, env, "_clock", "i()", &m3_libc_clock)));
_ (SuppressLookupFailure (m3_LinkRawFunction (module, env, "clock_ms", "i()", &m3_libc_clock_ms)));

_catch:
return result;
Expand Down
14 changes: 8 additions & 6 deletions src/m3_bind.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ _try {
_throwif (m3Err_malformedFunctionSignature, maxNumArgs < 0);
_throwif ("insane argument count", maxNumArgs > d_m3MaxSaneFunctionArgCount);

_ (AllocFuncType (& funcType, maxNumArgs));
const unsigned umaxNumArgs = (unsigned)maxNumArgs;

_ (AllocFuncType (& funcType, umaxNumArgs));

bool parsingArgs = false;
while (* sig)
Expand All @@ -65,19 +67,19 @@ _ (AllocFuncType (& funcType, maxNumArgs));
_throwif ("unknown argument type char", c_m3Type_unknown == type);

if (type == c_m3Type_none)
continue;
continue;

if (not parsingArgs)
{
_throwif ("malformed function signature; too many return types", funcType->numRets >= 1);

funcType->types [funcType->numRets++] = type;
d_FuncRetType(funcType, funcType->numRets++) = type;
}
else
{
_throwif (m3Err_malformedFunctionSignature, funcType->numArgs >= maxNumArgs); // forgot trailing ')' ?
_throwif (m3Err_malformedFunctionSignature, funcType->numArgs >= umaxNumArgs); // forgot trailing ')' ?

funcType->types [funcType->numRets + funcType->numArgs++] = type;
d_FuncArgType(funcType, funcType->numArgs++) = type;
}
}

Expand Down Expand Up @@ -148,7 +150,7 @@ M3Result FindAndLinkFunction (IM3Module io_module,
ccstr_t i_functionName,
ccstr_t i_signature,
voidptr_t i_function,
voidptr_t i_userdata)
voidptr_t i_userdata)
{
M3Result result = m3Err_functionLookupFailed;

Expand Down
110 changes: 110 additions & 0 deletions src/m3_code.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@

#include "m3_code.h"

#if d_m3RecordBacktraces
// Code mapping page ops

M3CodeMappingPage * NewCodeMappingPage (u32 i_minCapacity);
void FreeCodeMappingPage (M3CodeMappingPage * i_page);
#endif // d_m3RecordBacktraces

//---------------------------------------------------------------------------------------------------------------------------------


IM3CodePage NewCodePage (u32 i_minNumLines)
{
static u32 s_sequence = 0;
Expand All @@ -23,6 +33,16 @@ IM3CodePage NewCodePage (u32 i_minNumLines)
page->info.sequence = ++s_sequence;
page->info.numLines = (pageSize - sizeof (M3CodePageHeader)) / sizeof (code_t);

#if d_m3RecordBacktraces
page->info.mapping = NewCodeMappingPage (page->info.numLines);
if (!page->info.mapping)
{
m3Free (page);
return NULL;
}
page->info.mapping->basePC = GetPageStartPC(page);
#endif // d_m3RecordBacktraces

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

Expand All @@ -39,6 +59,9 @@ void FreeCodePages (IM3CodePage * io_list)
m3log (code, "free page: %d; %p; util: %3.1f%%", page->info.sequence, page, 100. * page->info.lineIndex / page->info.numLines);

IM3CodePage next = page->info.next;
#if d_m3RecordBacktraces
FreeCodeMappingPage (page->info.mapping);
#endif // d_m3RecordBacktraces
m3Free (page);
page = next;
}
Expand Down Expand Up @@ -79,6 +102,20 @@ void EmitWord64 (IM3CodePage i_page, const u64 i_word)
}


#if d_m3RecordBacktraces
void EmitMappingEntry (IM3CodePage i_page, u32 i_moduleOffset)
{
M3CodeMappingPage * page = i_page->info.mapping;
d_m3Assert (page->size < page->capacity);

M3CodeMapEntry * entry = & page->entries[page->size++];
pc_t pc = GetPagePC (i_page);

entry->pcOffset = pc - page->basePC;
entry->moduleOffset = i_moduleOffset;
}
#endif // d_m3RecordBacktraces

pc_t GetPageStartPC (IM3CodePage i_page)
{
return & i_page->code [0];
Expand Down Expand Up @@ -143,3 +180,76 @@ IM3CodePage GetEndCodePage (IM3CodePage i_list)

return end;
}

#if d_m3RecordBacktraces
bool ContainsPC (IM3CodePage i_page, pc_t i_pc)
{
return GetPageStartPC (i_page) <= i_pc && i_pc < GetPagePC (i_page);
}


bool MapPCToOffset (IM3CodePage i_page, pc_t i_pc, u32 * o_moduleOffset)
{
M3CodeMappingPage * mapping = i_page->info.mapping;

u32 pcOffset = i_pc - mapping->basePC;

u32 left = 0;
u32 right = mapping->size;

while (left < right)
{
u32 mid = left + (right - left) / 2;

if (mapping->entries[mid].pcOffset < pcOffset)
{
left = mid + 1;
}
else if (mapping->entries[mid].pcOffset > pcOffset)
{
right = mid;
}
else
{
*o_moduleOffset = mapping->entries[mid].moduleOffset;
return true;
}
}

// Getting here means left is now one more than the element we want.
if (left > 0)
{
left--;
*o_moduleOffset = mapping->entries[left].moduleOffset;
return true;
}
else return false;
}
#endif // d_m3RecordBacktraces

//---------------------------------------------------------------------------------------------------------------------------------


#if d_m3RecordBacktraces
M3CodeMappingPage * NewCodeMappingPage (u32 i_minCapacity)
{
M3CodeMappingPage * page;
u32 pageSize = sizeof (M3CodeMappingPage) + sizeof (M3CodeMapEntry) * i_minCapacity;

m3Alloc ((void **) & page, u8, pageSize);

if (page)
{
page->size = 0;
page->capacity = i_minCapacity;
}

return page;
}


void FreeCodeMappingPage (M3CodeMappingPage * i_page)
{
m3Free (i_page);
}
#endif // d_m3RecordBacktraces
30 changes: 30 additions & 0 deletions src/m3_code.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,49 @@ pc_t GetPagePC (IM3CodePage i_page);
void EmitWord_impl (IM3CodePage i_page, void* i_word);
void EmitWord32 (IM3CodePage i_page, u32 i_word);
void EmitWord64 (IM3CodePage i_page, u64 i_word);
# if d_m3RecordBacktraces
void EmitMappingEntry (IM3CodePage i_page, u32 i_moduleOffset);
# endif // d_m3RecordBacktraces

void PushCodePage (IM3CodePage * io_list, IM3CodePage i_codePage);
IM3CodePage PopCodePage (IM3CodePage * io_list);

IM3CodePage GetEndCodePage (IM3CodePage i_list); // i_list = NULL is valid
u32 CountCodePages (IM3CodePage i_list); // i_list = NULL is valid

# if d_m3RecordBacktraces
bool ContainsPC (IM3CodePage i_page, pc_t i_pc);
bool MapPCToOffset (IM3CodePage i_page, pc_t i_pc, u32 * o_moduleOffset);
# endif // d_m3RecordBacktraces

# ifdef DEBUG
void dump_code_page (IM3CodePage i_codePage, pc_t i_startPC);
# endif

#define EmitWord(page, val) EmitWord_impl(page, (void*)(val))

//---------------------------------------------------------------------------------------------------------------------------------

# if d_m3RecordBacktraces

typedef struct M3CodeMapEntry
{
u32 pcOffset;
u32 moduleOffset;
}
M3CodeMapEntry;

typedef struct M3CodeMappingPage
{
pc_t basePC;
u32 size;
u32 capacity;
M3CodeMapEntry entries [];
}
M3CodeMappingPage;

# endif // d_m3RecordBacktraces

d_m3EndExternC

#endif // m3_code_h
Loading

0 comments on commit 0821f8a

Please sign in to comment.