1 //
2 // m3_test.c
3 //
4 // Created by Steven Massey on 2/27/20.
5 // Copyright © 2020 Steven Massey. All rights reserved.
6 //
7
8 #include <stdio.h>
9
10 #include "wasm3_ext.h"
11 #include "m3_bind.h"
12
13 #define Test(NAME) if (RunTest (argc, argv, #NAME) != 0)
14 #define DisabledTest(NAME) printf ("\ndisabled: %s\n", #NAME); if (false)
15 #define expect(TEST) if (not (TEST)) { printf ("failed: (%s) on line: %d\n", #TEST, __LINE__); }
16
17
RunTest(int i_argc,const char * i_argv[],cstr_t i_name)18 bool RunTest (int i_argc, const char * i_argv [], cstr_t i_name)
19 {
20 cstr_t option = (i_argc == 2) ? i_argv [1] : NULL;
21
22 bool runningTest = option ? strcmp (option, i_name) == 0 : true;
23
24 if (runningTest)
25 printf ("\n test: %s\n", i_name);
26
27 return runningTest;
28 }
29
30
main(int argc,const char * argv[])31 int main (int argc, const char * argv [])
32 {
33 Test (signatures)
34 {
35 M3Result result;
36
37 IM3FuncType ftype = NULL;
38
39 result = SignatureToFuncType (& ftype, ""); expect (result == m3Err_malformedFunctionSignature)
40 m3_Free (ftype);
41
42 // implicit void return
43 result = SignatureToFuncType (& ftype, "()"); expect (result == m3Err_none)
44 m3_Free (ftype);
45
46 result = SignatureToFuncType (& ftype, " v () "); expect (result == m3Err_none)
47 expect (ftype->numRets == 0)
48 expect (ftype->numArgs == 0)
49 m3_Free (ftype);
50
51 result = SignatureToFuncType (& ftype, "f(IiF)"); expect (result == m3Err_none)
52 expect (ftype->numRets == 1)
53 expect (ftype->types [0] == c_m3Type_f32)
54 expect (ftype->numArgs == 3)
55 expect (ftype->types [1] == c_m3Type_i64)
56 expect (ftype->types [2] == c_m3Type_i32)
57 expect (ftype->types [3] == c_m3Type_f64)
58
59 IM3FuncType ftype2 = NULL;
60 result = SignatureToFuncType (& ftype2, "f(I i F)"); expect (result == m3Err_none);
61 expect (AreFuncTypesEqual (ftype, ftype2));
62 m3_Free (ftype);
63 m3_Free (ftype2);
64 }
65
66
67 Test (codepages.simple)
68 {
69 M3Environment env = { 0 };
70 M3Runtime runtime = { 0 };
71 runtime.environment = & env;
72
73 IM3CodePage page = AcquireCodePage (& runtime); expect (page);
74 expect (runtime.numCodePages == 1);
75 expect (runtime.numActiveCodePages == 1);
76
77 IM3CodePage page2 = AcquireCodePage (& runtime); expect (page2);
78 expect (runtime.numCodePages == 2);
79 expect (runtime.numActiveCodePages == 2);
80
81 ReleaseCodePage (& runtime, page); expect (runtime.numCodePages == 2);
82 expect (runtime.numActiveCodePages == 1);
83
84 ReleaseCodePage (& runtime, page2); expect (runtime.numCodePages == 2);
85 expect (runtime.numActiveCodePages == 0);
86
87 Runtime_Release (& runtime); expect (CountCodePages (env.pagesReleased) == 2);
88 Environment_Release (& env); expect (CountCodePages (env.pagesReleased) == 0);
89 }
90
91
92 Test (codepages.b)
93 {
94 const u32 c_numPages = 2000;
95 IM3CodePage pages [2000] = { NULL };
96
97 M3Environment env = { 0 };
98 M3Runtime runtime = { 0 };
99 runtime.environment = & env;
100
101 u32 numActive = 0;
102
103 for (u32 i = 0; i < 2000000; ++i)
104 {
105 u32 index = rand () % c_numPages; // printf ("%5u ", index);
106
107 if (pages [index] == NULL)
108 {
109 // printf ("acq\n");
110 pages [index] = AcquireCodePage (& runtime);
111 ++numActive;
112 }
113 else
114 {
115 // printf ("rel\n");
116 ReleaseCodePage (& runtime, pages [index]);
117 pages [index] = NULL;
118 --numActive;
119 }
120
121 expect (runtime.numActiveCodePages == numActive);
122 }
123
124 printf ("num pages: %d\n", runtime.numCodePages);
125
126 for (u32 i = 0; i < c_numPages; ++i)
127 {
128 if (pages [i])
129 {
130 ReleaseCodePage (& runtime, pages [i]);
131 pages [i] = NULL;
132 --numActive; expect (runtime.numActiveCodePages == numActive);
133 }
134 }
135
136 Runtime_Release (& runtime);
137 Environment_Release (& env);
138 }
139
140
141 Test (extensions)
142 {
143 M3Result result;
144
145 IM3Environment env = m3_NewEnvironment ();
146
147 IM3Runtime runtime = m3_NewRuntime (env, 1024, NULL);
148
149 IM3Module module = m3_NewModule (env);
150
151
152 i32 functionIndex = -1;
153
154 u8 wasm [5] = { 0x04, // size
155 0x00, // num local defs
156 0x41, 0x37, // i32.const= 55
157 0x0b // end block
158 };
159
160 // will partially fail (compilation) because module isn't attached to a runtime yet.
161 result = m3_InjectFunction (module, & functionIndex, "i()", wasm, true); expect (result != m3Err_none)
162 expect (functionIndex >= 0)
163
164 result = m3_LoadModule (runtime, module); expect (result == m3Err_none)
165
166 // try again
167 result = m3_InjectFunction (module, & functionIndex, "i()", wasm, true); expect (result == m3Err_none)
168
169 IM3Function function = m3_GetFunctionByIndex (module, functionIndex); expect (function)
170
171 if (function)
172 {
173 result = m3_CallV (function); expect (result == m3Err_none)
174 u32 ret = 0;
175 m3_GetResultsV (function, & ret); expect (ret == 55);
176 }
177
178 m3_FreeRuntime (runtime);
179 }
180
181 IM3Environment env = m3_NewEnvironment ();
182
183
184 Test (multireturn.a)
185 {
186 M3Result result;
187
188 IM3Runtime runtime = m3_NewRuntime (env, 1024, NULL);
189
190 # if 0
191 (module
192 (func (result i32 f32)
193
194 i32.const 1234
195 f32.const 5678.9
196 )
197
198 (export "main" (func 0))
199 )
200 # endif
201
202 u8 wasm [44] = {
203 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x06, 0x01, 0x60, 0x00, 0x02, 0x7f, 0x7d, 0x03, 0x02, 0x01, 0x00, 0x07, 0x08, 0x01, 0x04,
204 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x0a, 0x0c, 0x01, 0x0a, 0x00, 0x41, 0xd2, 0x09, 0x43, 0x33, 0x77, 0xb1, 0x45, 0x0b
205 };
206
207 IM3Module module;
208 result = m3_ParseModule (env, & module, wasm, 44); expect (result == m3Err_none)
209
210 result = m3_LoadModule (runtime, module); expect (result == m3Err_none)
211
212 IM3Function function = NULL;
213 result = m3_FindFunction (& function, runtime, "main"); expect (result == m3Err_none)
214 expect (function)
215 printf ("\n%s\n", result);
216
217 if (function)
218 {
219 result = m3_CallV (function); expect (result == m3Err_none)
220
221 i32 ret0 = 0;
222 f32 ret1 = 0.;
223 m3_GetResultsV (function, & ret0, & ret1);
224
225 printf ("%d %f\n", ret0, ret1);
226 }
227 }
228
229
230 Test (multireturn.branch)
231 {
232 # if 0
233 (module
234 (func (param i32) (result i32 i32)
235
236 i32.const 123
237 i32.const 456
238 i32.const 789
239
240 block (param i32 i32) (result i32 i32 i32)
241
242 local.get 0
243 local.get 0
244
245 local.get 0
246 br_if 0
247
248 drop
249
250 end
251
252 drop
253 drop
254 )
255
256 (export "main" (func 0))
257 )
258 # endif
259 }
260
261 return 0;
262 }
263