Skip to content

Commit 0821f8a

Browse files
committed
Update to v0.4.9
1 parent f634d5d commit 0821f8a

24 files changed

+1375
-858
lines changed

src/m3_api_defs.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,13 @@
1818
#define m3ApiGetArg(TYPE, NAME) TYPE NAME = * ((TYPE *) (_sp++));
1919
#define m3ApiGetArgMem(TYPE, NAME) TYPE NAME = (TYPE)m3ApiOffsetToPtr(* ((u32 *) (_sp++)));
2020

21-
#define m3ApiRawFunction(NAME) const void * NAME (IM3Runtime runtime, uint64_t * _sp, void * _mem, void * userdata)
21+
#if d_m3SkipMemoryBoundsCheck
22+
# define m3ApiCheckMem(off, len)
23+
#else
24+
# define m3ApiCheckMem(off, len) { if (UNLIKELY(off == _mem || ((u64)(off) + (len)) > ((u64)(_mem)+runtime->memory.mallocated->length))) m3ApiTrap(m3Err_trapOutOfBoundsMemoryAccess); }
25+
#endif
26+
27+
#define m3ApiRawFunction(NAME) const void * NAME (IM3Runtime runtime, IM3ImportContext _ctx, uint64_t * _sp, void * _mem)
2228
#define m3ApiReturn(VALUE) { *raw_return = (VALUE); return m3Err_none; }
2329
#define m3ApiTrap(VALUE) { return VALUE; }
2430
#define m3ApiSuccess() { return m3Err_none; }

src/m3_api_libc.c

+24-29
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ m3ApiRawFunction(m3_libc_memset)
3939
m3ApiGetArg (int32_t, i_value)
4040
m3ApiGetArg (int32_t, i_size)
4141

42+
m3ApiCheckMem(i_ptr, i_size);
43+
4244
u32 result = m3ApiPtrToOffset(memset (i_ptr, i_value, i_size));
4345
m3ApiReturn(result);
4446
}
@@ -51,15 +53,33 @@ m3ApiRawFunction(m3_libc_memmove)
5153
m3ApiGetArgMem (void*, i_src)
5254
m3ApiGetArg (int32_t, i_size)
5355

56+
m3ApiCheckMem(o_dst, i_size);
57+
m3ApiCheckMem(i_src, i_size);
58+
5459
u32 result = m3ApiPtrToOffset(memmove (o_dst, i_src, i_size));
5560
m3ApiReturn(result);
5661
}
5762

58-
m3ApiRawFunction(m3_libc_clock)
63+
m3ApiRawFunction(m3_libc_print)
5964
{
6065
m3ApiReturnType (uint32_t)
6166

62-
m3ApiReturn(clock());
67+
m3ApiGetArgMem (void*, i_ptr)
68+
m3ApiGetArg (uint32_t, i_size)
69+
70+
m3ApiCheckMem(i_ptr, i_size);
71+
72+
fwrite(i_ptr, i_size, 1, stdout);
73+
fflush(stdout);
74+
75+
m3ApiReturn(i_size);
76+
}
77+
78+
m3ApiRawFunction(m3_libc_clock_ms)
79+
{
80+
m3ApiReturnType (uint32_t)
81+
82+
m3ApiReturn(clock() / (CLOCKS_PER_SEC/1000));
6383
}
6484

6585
static
@@ -76,33 +96,11 @@ m3ApiRawFunction(m3_spectest_dummy)
7696
m3ApiSuccess();
7797
}
7898

79-
m3ApiRawFunction(m3_wasm3_raw_sum)
80-
{
81-
m3ApiReturnType (int64_t)
82-
m3ApiGetArg (int32_t, val1)
83-
m3ApiGetArg (int32_t, val2)
84-
m3ApiGetArg (int32_t, val3)
85-
m3ApiGetArg (int32_t, val4)
86-
87-
m3ApiReturn(val1 + val2 + val3 + val4);
88-
89-
m3ApiSuccess();
90-
}
91-
92-
/* TODO: implement direct native function calls (using libffi?)
93-
i64 m3_wasm3_native_sum(i32 val1, i32 val2, i32 val3, i32 val4)
94-
{
95-
return val1 + val2 + val3 + val4;
96-
}
97-
*/
98-
99-
10099
M3Result m3_LinkSpecTest (IM3Module module)
101100
{
102101
M3Result result = m3Err_none;
103102

104103
const char* spectest = "spectest";
105-
const char* wasm3 = "wasm3";
106104

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

115-
116-
_ (SuppressLookupFailure (m3_LinkRawFunction (module, wasm3, "raw_sum", "I(iiii)", &m3_wasm3_raw_sum)));
117-
//_ (SuppressLookupFailure (m3_LinkCFunction (module, wasm3, "native_sum", "I(iiii)", &m3_wasm3_native_sum)));
118-
119113
_catch:
120114
return result;
121115
}
@@ -127,12 +121,13 @@ M3Result m3_LinkLibC (IM3Module module)
127121

128122
const char* env = "env";
129123

124+
_ (SuppressLookupFailure (m3_LinkRawFunction (module, env, "_debug", "i(*i)", &m3_libc_print)));
130125
_ (SuppressLookupFailure (m3_LinkRawFunction (module, env, "_memset", "*(*ii)", &m3_libc_memset)));
131126
_ (SuppressLookupFailure (m3_LinkRawFunction (module, env, "_memmove", "*(**i)", &m3_libc_memmove)));
132127
_ (SuppressLookupFailure (m3_LinkRawFunction (module, env, "_memcpy", "*(**i)", &m3_libc_memmove))); // just alias of memmove
133128
_ (SuppressLookupFailure (m3_LinkRawFunction (module, env, "_abort", "v()", &m3_libc_abort)));
134129
_ (SuppressLookupFailure (m3_LinkRawFunction (module, env, "_exit", "v(i)", &m3_libc_exit)));
135-
_ (SuppressLookupFailure (m3_LinkRawFunction (module, env, "_clock", "i()", &m3_libc_clock)));
130+
_ (SuppressLookupFailure (m3_LinkRawFunction (module, env, "clock_ms", "i()", &m3_libc_clock_ms)));
136131

137132
_catch:
138133
return result;

src/m3_bind.c

+8-6
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ _try {
4343
_throwif (m3Err_malformedFunctionSignature, maxNumArgs < 0);
4444
_throwif ("insane argument count", maxNumArgs > d_m3MaxSaneFunctionArgCount);
4545

46-
_ (AllocFuncType (& funcType, maxNumArgs));
46+
const unsigned umaxNumArgs = (unsigned)maxNumArgs;
47+
48+
_ (AllocFuncType (& funcType, umaxNumArgs));
4749

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

6769
if (type == c_m3Type_none)
68-
continue;
70+
continue;
6971

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

74-
funcType->types [funcType->numRets++] = type;
76+
d_FuncRetType(funcType, funcType->numRets++) = type;
7577
}
7678
else
7779
{
78-
_throwif (m3Err_malformedFunctionSignature, funcType->numArgs >= maxNumArgs); // forgot trailing ')' ?
80+
_throwif (m3Err_malformedFunctionSignature, funcType->numArgs >= umaxNumArgs); // forgot trailing ')' ?
7981

80-
funcType->types [funcType->numRets + funcType->numArgs++] = type;
82+
d_FuncArgType(funcType, funcType->numArgs++) = type;
8183
}
8284
}
8385

@@ -148,7 +150,7 @@ M3Result FindAndLinkFunction (IM3Module io_module,
148150
ccstr_t i_functionName,
149151
ccstr_t i_signature,
150152
voidptr_t i_function,
151-
voidptr_t i_userdata)
153+
voidptr_t i_userdata)
152154
{
153155
M3Result result = m3Err_functionLookupFailed;
154156

src/m3_code.c

+110
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,16 @@
77

88
#include "m3_code.h"
99

10+
#if d_m3RecordBacktraces
11+
// Code mapping page ops
12+
13+
M3CodeMappingPage * NewCodeMappingPage (u32 i_minCapacity);
14+
void FreeCodeMappingPage (M3CodeMappingPage * i_page);
15+
#endif // d_m3RecordBacktraces
16+
17+
//---------------------------------------------------------------------------------------------------------------------------------
18+
19+
1020
IM3CodePage NewCodePage (u32 i_minNumLines)
1121
{
1222
static u32 s_sequence = 0;
@@ -23,6 +33,16 @@ IM3CodePage NewCodePage (u32 i_minNumLines)
2333
page->info.sequence = ++s_sequence;
2434
page->info.numLines = (pageSize - sizeof (M3CodePageHeader)) / sizeof (code_t);
2535

36+
#if d_m3RecordBacktraces
37+
page->info.mapping = NewCodeMappingPage (page->info.numLines);
38+
if (!page->info.mapping)
39+
{
40+
m3Free (page);
41+
return NULL;
42+
}
43+
page->info.mapping->basePC = GetPageStartPC(page);
44+
#endif // d_m3RecordBacktraces
45+
2646
m3log (runtime, "new page: %p; seq: %d; bytes: %d; lines: %d", GetPagePC (page), page->info.sequence, pageSize, page->info.numLines);
2747
}
2848

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

4161
IM3CodePage next = page->info.next;
62+
#if d_m3RecordBacktraces
63+
FreeCodeMappingPage (page->info.mapping);
64+
#endif // d_m3RecordBacktraces
4265
m3Free (page);
4366
page = next;
4467
}
@@ -79,6 +102,20 @@ void EmitWord64 (IM3CodePage i_page, const u64 i_word)
79102
}
80103

81104

105+
#if d_m3RecordBacktraces
106+
void EmitMappingEntry (IM3CodePage i_page, u32 i_moduleOffset)
107+
{
108+
M3CodeMappingPage * page = i_page->info.mapping;
109+
d_m3Assert (page->size < page->capacity);
110+
111+
M3CodeMapEntry * entry = & page->entries[page->size++];
112+
pc_t pc = GetPagePC (i_page);
113+
114+
entry->pcOffset = pc - page->basePC;
115+
entry->moduleOffset = i_moduleOffset;
116+
}
117+
#endif // d_m3RecordBacktraces
118+
82119
pc_t GetPageStartPC (IM3CodePage i_page)
83120
{
84121
return & i_page->code [0];
@@ -143,3 +180,76 @@ IM3CodePage GetEndCodePage (IM3CodePage i_list)
143180

144181
return end;
145182
}
183+
184+
#if d_m3RecordBacktraces
185+
bool ContainsPC (IM3CodePage i_page, pc_t i_pc)
186+
{
187+
return GetPageStartPC (i_page) <= i_pc && i_pc < GetPagePC (i_page);
188+
}
189+
190+
191+
bool MapPCToOffset (IM3CodePage i_page, pc_t i_pc, u32 * o_moduleOffset)
192+
{
193+
M3CodeMappingPage * mapping = i_page->info.mapping;
194+
195+
u32 pcOffset = i_pc - mapping->basePC;
196+
197+
u32 left = 0;
198+
u32 right = mapping->size;
199+
200+
while (left < right)
201+
{
202+
u32 mid = left + (right - left) / 2;
203+
204+
if (mapping->entries[mid].pcOffset < pcOffset)
205+
{
206+
left = mid + 1;
207+
}
208+
else if (mapping->entries[mid].pcOffset > pcOffset)
209+
{
210+
right = mid;
211+
}
212+
else
213+
{
214+
*o_moduleOffset = mapping->entries[mid].moduleOffset;
215+
return true;
216+
}
217+
}
218+
219+
// Getting here means left is now one more than the element we want.
220+
if (left > 0)
221+
{
222+
left--;
223+
*o_moduleOffset = mapping->entries[left].moduleOffset;
224+
return true;
225+
}
226+
else return false;
227+
}
228+
#endif // d_m3RecordBacktraces
229+
230+
//---------------------------------------------------------------------------------------------------------------------------------
231+
232+
233+
#if d_m3RecordBacktraces
234+
M3CodeMappingPage * NewCodeMappingPage (u32 i_minCapacity)
235+
{
236+
M3CodeMappingPage * page;
237+
u32 pageSize = sizeof (M3CodeMappingPage) + sizeof (M3CodeMapEntry) * i_minCapacity;
238+
239+
m3Alloc ((void **) & page, u8, pageSize);
240+
241+
if (page)
242+
{
243+
page->size = 0;
244+
page->capacity = i_minCapacity;
245+
}
246+
247+
return page;
248+
}
249+
250+
251+
void FreeCodeMappingPage (M3CodeMappingPage * i_page)
252+
{
253+
m3Free (i_page);
254+
}
255+
#endif // d_m3RecordBacktraces

src/m3_code.h

+30
Original file line numberDiff line numberDiff line change
@@ -32,19 +32,49 @@ pc_t GetPagePC (IM3CodePage i_page);
3232
void EmitWord_impl (IM3CodePage i_page, void* i_word);
3333
void EmitWord32 (IM3CodePage i_page, u32 i_word);
3434
void EmitWord64 (IM3CodePage i_page, u64 i_word);
35+
# if d_m3RecordBacktraces
36+
void EmitMappingEntry (IM3CodePage i_page, u32 i_moduleOffset);
37+
# endif // d_m3RecordBacktraces
3538

3639
void PushCodePage (IM3CodePage * io_list, IM3CodePage i_codePage);
3740
IM3CodePage PopCodePage (IM3CodePage * io_list);
3841

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

45+
# if d_m3RecordBacktraces
46+
bool ContainsPC (IM3CodePage i_page, pc_t i_pc);
47+
bool MapPCToOffset (IM3CodePage i_page, pc_t i_pc, u32 * o_moduleOffset);
48+
# endif // d_m3RecordBacktraces
49+
4250
# ifdef DEBUG
4351
void dump_code_page (IM3CodePage i_codePage, pc_t i_startPC);
4452
# endif
4553

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

56+
//---------------------------------------------------------------------------------------------------------------------------------
57+
58+
# if d_m3RecordBacktraces
59+
60+
typedef struct M3CodeMapEntry
61+
{
62+
u32 pcOffset;
63+
u32 moduleOffset;
64+
}
65+
M3CodeMapEntry;
66+
67+
typedef struct M3CodeMappingPage
68+
{
69+
pc_t basePC;
70+
u32 size;
71+
u32 capacity;
72+
M3CodeMapEntry entries [];
73+
}
74+
M3CodeMappingPage;
75+
76+
# endif // d_m3RecordBacktraces
77+
4878
d_m3EndExternC
4979

5080
#endif // m3_code_h

0 commit comments

Comments
 (0)