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