Skip to content

Commit a2499c4

Browse files
committed
Update wasm3
1 parent bc181e1 commit a2499c4

25 files changed

+2574
-1589
lines changed

src/m3_api_defs.h

+1-47
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,2 @@
1-
//
2-
// m3_api_defs.h
3-
//
4-
// Created by Volodymyr Shymanskyy on 12/20/19.
5-
// Copyright © 2019 Volodymyr Shymanskyy. All rights reserved.
6-
//
1+
#warning "Using m3_api_defs.h is deprecated. Just include wasm3.h"
72

8-
#ifndef m3_api_defs_h
9-
#define m3_api_defs_h
10-
11-
#include "m3_core.h"
12-
13-
// TODO: perform bounds checks
14-
#define m3ApiOffsetToPtr(offset) (void*)((u8*)_mem + (u32)(offset))
15-
#define m3ApiPtrToOffset(ptr) (u32)((u8*)ptr - (u8*)_mem)
16-
17-
#define m3ApiReturnType(TYPE) TYPE* raw_return = ((TYPE*) (_sp));
18-
#define m3ApiGetArg(TYPE, NAME) TYPE NAME = * ((TYPE *) (_sp++));
19-
#define m3ApiGetArgMem(TYPE, NAME) TYPE NAME = (TYPE)m3ApiOffsetToPtr(* ((u32 *) (_sp++)));
20-
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)
28-
#define m3ApiReturn(VALUE) { *raw_return = (VALUE); return m3Err_none; }
29-
#define m3ApiTrap(VALUE) { return VALUE; }
30-
#define m3ApiSuccess() { return m3Err_none; }
31-
32-
# if defined(M3_BIG_ENDIAN)
33-
# define m3ApiReadMem16(ptr) __builtin_bswap16((* (u16 *)(ptr)))
34-
# define m3ApiReadMem32(ptr) __builtin_bswap32((* (u32 *)(ptr)))
35-
# define m3ApiReadMem64(ptr) __builtin_bswap64((* (u64 *)(ptr)))
36-
# define m3ApiWriteMem16(ptr, val) { * (u16 *)(ptr) = __builtin_bswap16((val)); }
37-
# define m3ApiWriteMem32(ptr, val) { * (u32 *)(ptr) = __builtin_bswap32((val)); }
38-
# define m3ApiWriteMem64(ptr, val) { * (u64 *)(ptr) = __builtin_bswap64((val)); }
39-
# else
40-
# define m3ApiReadMem16(ptr) (* (u16 *)(ptr))
41-
# define m3ApiReadMem32(ptr) (* (u32 *)(ptr))
42-
# define m3ApiReadMem64(ptr) (* (u64 *)(ptr))
43-
# define m3ApiWriteMem16(ptr, val) { * (u16 *)(ptr) = (val); }
44-
# define m3ApiWriteMem32(ptr, val) { * (u32 *)(ptr) = (val); }
45-
# define m3ApiWriteMem64(ptr, val) { * (u64 *)(ptr) = (val); }
46-
# endif
47-
48-
#endif // m3_api_defs_h

src/m3_api_libc.c

+115-10
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,15 @@
99

1010
#include "m3_api_libc.h"
1111

12-
#include "m3_api_defs.h"
1312
#include "m3_env.h"
1413
#include "m3_exception.h"
1514

1615
#include <time.h>
1716
#include <errno.h>
1817
#include <stdio.h>
1918

19+
typedef uint32_t wasm_ptr_t;
20+
typedef uint32_t wasm_size_t;
2021

2122
m3ApiRawFunction(m3_libc_abort)
2223
{
@@ -35,9 +36,9 @@ m3ApiRawFunction(m3_libc_memset)
3536
{
3637
m3ApiReturnType (int32_t)
3738

38-
m3ApiGetArgMem (void*, i_ptr)
39-
m3ApiGetArg (int32_t, i_value)
40-
m3ApiGetArg (int32_t, i_size)
39+
m3ApiGetArgMem (void*, i_ptr)
40+
m3ApiGetArg (int32_t, i_value)
41+
m3ApiGetArg (wasm_size_t, i_size)
4142

4243
m3ApiCheckMem(i_ptr, i_size);
4344

@@ -49,9 +50,9 @@ m3ApiRawFunction(m3_libc_memmove)
4950
{
5051
m3ApiReturnType (int32_t)
5152

52-
m3ApiGetArgMem (void*, o_dst)
53-
m3ApiGetArgMem (void*, i_src)
54-
m3ApiGetArg (int32_t, i_size)
53+
m3ApiGetArgMem (void*, o_dst)
54+
m3ApiGetArgMem (void*, i_src)
55+
m3ApiGetArg (wasm_size_t, i_size)
5556

5657
m3ApiCheckMem(o_dst, i_size);
5758
m3ApiCheckMem(i_src, i_size);
@@ -64,8 +65,8 @@ m3ApiRawFunction(m3_libc_print)
6465
{
6566
m3ApiReturnType (uint32_t)
6667

67-
m3ApiGetArgMem (void*, i_ptr)
68-
m3ApiGetArg (uint32_t, i_size)
68+
m3ApiGetArgMem (void*, i_ptr)
69+
m3ApiGetArg (wasm_size_t, i_size)
6970

7071
m3ApiCheckMem(i_ptr, i_size);
7172

@@ -75,11 +76,114 @@ m3ApiRawFunction(m3_libc_print)
7576
m3ApiReturn(i_size);
7677
}
7778

79+
static
80+
void internal_itoa(int n, char s[], int radix)
81+
{
82+
static char const HEXDIGITS[0x10] = {
83+
'0', '1', '2', '3', '4', '5', '6', '7',
84+
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
85+
};
86+
87+
int i, j, sign;
88+
char c;
89+
90+
if ((sign = n) < 0) { n = -n; }
91+
i = 0;
92+
do {
93+
s[i++] = HEXDIGITS[n % radix];
94+
} while ((n /= radix) > 0);
95+
96+
if (sign < 0) { s[i++] = '-'; }
97+
s[i] = '\0';
98+
99+
// reverse
100+
for (i = 0, j = strlen(s)-1; i<j; i++, j--) {
101+
c = s[i];
102+
s[i] = s[j];
103+
s[j] = c;
104+
}
105+
}
106+
107+
m3ApiRawFunction(m3_libc_printf)
108+
{
109+
m3ApiReturnType (int32_t)
110+
111+
m3ApiGetArgMem (const char*, i_fmt)
112+
m3ApiGetArgMem (wasm_ptr_t*, i_args)
113+
114+
if (m3ApiIsNullPtr(i_fmt)) {
115+
m3ApiReturn(0);
116+
}
117+
118+
m3ApiCheckMem(i_fmt, 1);
119+
size_t fmt_len = strnlen(i_fmt, 1024);
120+
m3ApiCheckMem(i_fmt, fmt_len+1); // include `\0`
121+
122+
FILE* file = stdout;
123+
124+
int32_t length = 0;
125+
char ch;
126+
while ((ch = *i_fmt++)) {
127+
if ( '%' != ch ) {
128+
putc(ch, file);
129+
length++;
130+
continue;
131+
}
132+
ch = *i_fmt++;
133+
switch (ch) {
134+
case 'c': {
135+
m3ApiCheckMem(i_args, sizeof(wasm_ptr_t));
136+
char char_temp = *i_args++;
137+
fputc(char_temp, file);
138+
length++;
139+
break;
140+
}
141+
case 'd':
142+
case 'x': {
143+
m3ApiCheckMem(i_args, sizeof(wasm_ptr_t));
144+
int int_temp = *i_args++;
145+
char buffer[32] = { 0, };
146+
internal_itoa(int_temp, buffer, (ch == 'x') ? 16 : 10);
147+
fputs(buffer, file);
148+
length += strnlen(buffer, sizeof(buffer));
149+
break;
150+
}
151+
case 's': {
152+
m3ApiCheckMem(i_args, sizeof(wasm_ptr_t));
153+
const char* string_temp;
154+
size_t string_len;
155+
156+
string_temp = (const char*)m3ApiOffsetToPtr(*i_args++);
157+
if (m3ApiIsNullPtr(string_temp)) {
158+
string_temp = "(null)";
159+
string_len = 6;
160+
} else {
161+
string_len = strnlen(string_temp, 1024);
162+
m3ApiCheckMem(string_temp, string_len+1);
163+
}
164+
165+
fwrite(string_temp, 1, string_len, file);
166+
length += string_len;
167+
break;
168+
default:
169+
fputc(ch, file);
170+
length++;
171+
break;
172+
}
173+
}
174+
}
175+
176+
m3ApiReturn(length);
177+
}
178+
78179
m3ApiRawFunction(m3_libc_clock_ms)
79180
{
80181
m3ApiReturnType (uint32_t)
81-
182+
#ifdef CLOCKS_PER_SEC
82183
m3ApiReturn(clock() / (CLOCKS_PER_SEC/1000));
184+
#else
185+
m3ApiReturn(clock());
186+
#endif
83187
}
84188

85189
static
@@ -128,6 +232,7 @@ _ (SuppressLookupFailure (m3_LinkRawFunction (module, env, "_memcpy",
128232
_ (SuppressLookupFailure (m3_LinkRawFunction (module, env, "_abort", "v()", &m3_libc_abort)));
129233
_ (SuppressLookupFailure (m3_LinkRawFunction (module, env, "_exit", "v(i)", &m3_libc_exit)));
130234
_ (SuppressLookupFailure (m3_LinkRawFunction (module, env, "clock_ms", "i()", &m3_libc_clock_ms)));
235+
_ (SuppressLookupFailure (m3_LinkRawFunction (module, env, "printf", "i(**)", &m3_libc_printf)));
131236

132237
_catch:
133238
return result;

src/m3_bind.c

+24-18
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ M3Result SignatureToFuncType (IM3FuncType * o_functionType, ccstr_t i_signatur
3030
M3Result result = m3Err_none;
3131

3232
IM3FuncType funcType = NULL;
33+
3334
_try {
3435
if (not o_functionType)
3536
_throw ("null function type");
@@ -39,22 +40,26 @@ _try {
3940

4041
cstr_t sig = i_signature;
4142

42-
int maxNumArgs = strlen (i_signature) - 2; // "()"
43-
_throwif (m3Err_malformedFunctionSignature, maxNumArgs < 0);
44-
_throwif ("insane argument count", maxNumArgs > d_m3MaxSaneFunctionArgCount);
43+
size_t maxNumTypes = strlen (i_signature);
44+
45+
// assume min signature is "()"
46+
_throwif (m3Err_malformedFunctionSignature, maxNumTypes < 2);
47+
maxNumTypes -= 2;
4548

46-
const unsigned umaxNumArgs = (unsigned)maxNumArgs;
49+
_throwif (m3Err_tooManyArgsRets, maxNumTypes > d_m3MaxSaneFunctionArgRetCount);
4750

48-
_ (AllocFuncType (& funcType, umaxNumArgs));
51+
_ (AllocFuncType (& funcType, (u32) maxNumTypes));
4952

50-
bool parsingArgs = false;
53+
u8 * typelist = funcType->types;
54+
55+
bool parsingRets = true;
5156
while (* sig)
5257
{
5358
char typeChar = * sig++;
5459

5560
if (typeChar == '(')
5661
{
57-
parsingArgs = true;
62+
parsingRets = false;
5863
continue;
5964
}
6065
else if ( typeChar == ' ')
@@ -69,24 +74,24 @@ _ (AllocFuncType (& funcType, umaxNumArgs));
6974
if (type == c_m3Type_none)
7075
continue;
7176

72-
if (not parsingArgs)
77+
if (parsingRets)
7378
{
74-
_throwif ("malformed function signature; too many return types", funcType->numRets >= 1);
75-
76-
d_FuncRetType(funcType, funcType->numRets++) = type;
79+
_throwif ("malformed signature; return count overflow", funcType->numRets >= maxNumTypes);
80+
funcType->numRets++;
81+
*typelist++ = type;
7782
}
7883
else
7984
{
80-
_throwif (m3Err_malformedFunctionSignature, funcType->numArgs >= umaxNumArgs); // forgot trailing ')' ?
81-
82-
d_FuncArgType(funcType, funcType->numArgs++) = type;
85+
_throwif ("malformed signature; arg count overflow", (u32)(funcType->numRets) + funcType->numArgs >= maxNumTypes);
86+
funcType->numArgs++;
87+
*typelist++ = type;
8388
}
8489
}
8590

8691
} _catch:
8792

8893
if (result)
89-
m3Free (funcType); // nulls funcType
94+
m3_Free (funcType);
9095

9196
* o_functionType = funcType;
9297

@@ -112,7 +117,7 @@ _ (SignatureToFuncType (& ftype, i_linkingSignature));
112117

113118
_catch:
114119

115-
m3Free (ftype);
120+
m3_Free (ftype);
116121

117122
return result;
118123
}
@@ -123,8 +128,9 @@ M3Result LinkRawFunction (IM3Module io_module, IM3Function io_function, ccstr
123128
M3Result result = m3Err_none; d_m3Assert (io_module->runtime);
124129

125130
_try {
126-
_ (ValidateSignature (io_function, signature));
127-
131+
if (signature) {
132+
_ (ValidateSignature (io_function, signature));
133+
}
128134
IM3CodePage page = AcquireCodePageWithCapacity (io_module->runtime, 4);
129135

130136
if (page)

0 commit comments

Comments
 (0)