Fix spelling
[mono-project.git] / sdks / wasm / driver.c
blobbed86b9e487d93bc51e18b71003fcad2a3e912a4
1 #include <emscripten.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <stdint.h>
6 #include <assert.h>
8 #include <mono/metadata/assembly.h>
9 #include <mono/metadata/tokentype.h>
10 #include <mono/utils/mono-logger.h>
11 #include <mono/utils/mono-dl-fallback.h>
12 #include <mono/jit/jit.h>
14 // FIXME: Autogenerate this
16 typedef struct {
17 const char *name;
18 void *func;
19 } PinvokeImport;
21 void SystemNative_ConvertErrorPalToPlatform ();
22 void SystemNative_ConvertErrorPlatformToPal ();
23 void SystemNative_StrErrorR ();
24 void SystemNative_MemSet ();
25 void SystemNative_GetEGid ();
26 void SystemNative_GetEUid ();
27 void SystemNative_GetPwNamR ();
28 void SystemNative_GetPwUidR ();
29 void SystemNative_SetEUid ();
30 void SystemNative_GetAbsoluteTime ();
31 void SystemNative_GetTimebaseInfo ();
32 void SystemNative_GetTimestamp ();
33 void SystemNative_GetTimestampResolution ();
34 void SystemNative_UTime ();
35 void SystemNative_UTimes ();
36 void SystemNative_Access ();
37 void SystemNative_ChDir ();
38 void SystemNative_ChMod ();
39 void SystemNative_Close ();
40 void SystemNative_CloseDir ();
41 void SystemNative_CopyFile ();
42 void SystemNative_Dup ();
43 void SystemNative_FChMod ();
44 void SystemNative_FLock ();
45 void SystemNative_FStat2 ();
46 void SystemNative_FSync ();
47 void SystemNative_FTruncate ();
48 void SystemNative_FcntlCanGetSetPipeSz ();
49 void SystemNative_FcntlGetPipeSz ();
50 void SystemNative_FcntlSetCloseOnExec ();
51 void SystemNative_FcntlSetIsNonBlocking ();
52 void SystemNative_FcntlSetPipeSz ();
53 void SystemNative_FnMatch ();
54 void SystemNative_GetLine ();
55 void SystemNative_GetPeerID ();
56 void SystemNative_GetReadDirRBufferSize ();
57 void SystemNative_INotifyAddWatch ();
58 void SystemNative_INotifyInit ();
59 void SystemNative_INotifyRemoveWatch ();
60 void SystemNative_LSeek ();
61 void SystemNative_LStat2 ();
62 void SystemNative_Link ();
63 void SystemNative_LockFileRegion ();
64 void SystemNative_MAdvise ();
65 void SystemNative_MLock ();
66 void SystemNative_MMap ();
67 void SystemNative_MProtect ();
68 void SystemNative_MSync ();
69 void SystemNative_MUnlock ();
70 void SystemNative_MUnmap ();
71 void SystemNative_MkDir ();
72 void SystemNative_MksTemps ();
73 void SystemNative_Open ();
74 void SystemNative_OpenDir ();
75 void SystemNative_Pipe ();
76 void SystemNative_Poll ();
77 void SystemNative_PosixFAdvise ();
78 void SystemNative_Read ();
79 void SystemNative_ReadDirR ();
80 void SystemNative_ReadLink ();
81 void SystemNative_RealPath ();
82 void SystemNative_Rename ();
83 void SystemNative_RmDir ();
84 void SystemNative_ShmOpen ();
85 void SystemNative_ShmUnlink ();
86 void SystemNative_Stat2 ();
87 void SystemNative_Sync ();
88 void SystemNative_SysConf ();
89 void SystemNative_Unlink ();
90 void SystemNative_Write ();
91 void SystemNative_Accept ();
92 void SystemNative_Bind ();
93 void SystemNative_CloseSocketEventPort ();
94 void SystemNative_Connect ();
95 void SystemNative_CreateSocketEventBuffer ();
96 void SystemNative_CreateSocketEventPort ();
97 void SystemNative_FreeHostEntry ();
98 void SystemNative_FreeSocketEventBuffer ();
99 void SystemNative_GetAddressFamily ();
100 void SystemNative_GetAtOutOfBandMark ();
101 void SystemNative_GetBytesAvailable ();
102 void SystemNative_GetControlMessageBufferSize ();
103 void SystemNative_GetDomainName ();
104 void SystemNative_GetDomainSocketSizes ();
105 void SystemNative_GetHostEntryForName ();
106 void SystemNative_GetHostName ();
107 void SystemNative_GetIPSocketAddressSizes ();
108 void SystemNative_GetIPv4Address ();
109 void SystemNative_GetIPv4MulticastOption ();
110 void SystemNative_GetIPv6Address ();
111 void SystemNative_GetIPv6MulticastOption ();
112 void SystemNative_GetLingerOption ();
113 void SystemNative_GetNameInfo ();
114 void SystemNative_GetNextIPAddress ();
115 void SystemNative_GetPeerName ();
116 void SystemNative_GetPeerUserName ();
117 void SystemNative_GetPort ();
118 void SystemNative_GetSockName ();
119 void SystemNative_GetSockOpt ();
120 void SystemNative_GetSocketErrorOption ();
121 void SystemNative_Listen ();
122 void SystemNative_PlatformSupportsDualModeIPv4PacketInfo ();
123 void SystemNative_ReceiveMessage ();
124 void SystemNative_SendFile ();
125 void SystemNative_SendMessage ();
126 void SystemNative_SetAddressFamily ();
127 void SystemNative_SetIPv4Address ();
128 void SystemNative_SetIPv4MulticastOption ();
129 void SystemNative_SetIPv6Address ();
130 void SystemNative_SetIPv6MulticastOption ();
131 void SystemNative_SetLingerOption ();
132 void SystemNative_SetPort ();
133 void SystemNative_SetReceiveTimeout ();
134 void SystemNative_SetSendTimeout ();
135 void SystemNative_SetSockOpt ();
136 void SystemNative_Shutdown ();
137 void SystemNative_Socket ();
138 void SystemNative_TryChangeSocketEventRegistration ();
139 void SystemNative_TryGetIPPacketInformation ();
140 void SystemNative_WaitForSocketEvents ();
141 void SystemNative_MapTcpState ();
142 void SystemNative_GetNonCryptographicallySecureRandomBytes ();
144 static PinvokeImport sysnative_imports [] = {
145 {"SystemNative_ConvertErrorPalToPlatform", SystemNative_ConvertErrorPalToPlatform},
146 {"SystemNative_ConvertErrorPlatformToPal", SystemNative_ConvertErrorPlatformToPal},
147 {"SystemNative_StrErrorR", SystemNative_StrErrorR},
148 {"SystemNative_MemSet", SystemNative_MemSet},
149 {"SystemNative_GetEGid", SystemNative_GetEGid},
150 {"SystemNative_GetEUid", SystemNative_GetEUid},
151 {"SystemNative_GetPwNamR", SystemNative_GetPwNamR},
152 {"SystemNative_GetPwUidR", SystemNative_GetPwUidR},
153 {"SystemNative_SetEUid", SystemNative_SetEUid},
154 {"SystemNative_GetAbsoluteTime", SystemNative_GetAbsoluteTime},
155 {"SystemNative_GetTimebaseInfo", SystemNative_GetTimebaseInfo},
156 {"SystemNative_GetTimestamp", SystemNative_GetTimestamp},
157 {"SystemNative_GetTimestampResolution", SystemNative_GetTimestampResolution},
158 {"SystemNative_UTime", SystemNative_UTime},
159 {"SystemNative_UTimes", SystemNative_UTimes},
160 {"SystemNative_Access", SystemNative_Access},
161 {"SystemNative_ChDir", SystemNative_ChDir},
162 {"SystemNative_ChMod", SystemNative_ChMod},
163 {"SystemNative_Close", SystemNative_Close},
164 {"SystemNative_CloseDir", SystemNative_CloseDir},
165 {"SystemNative_CopyFile", SystemNative_CopyFile},
166 {"SystemNative_Dup", SystemNative_Dup},
167 {"SystemNative_FChMod", SystemNative_FChMod},
168 {"SystemNative_FLock", SystemNative_FLock},
169 {"SystemNative_FStat2", SystemNative_FStat2},
170 {"SystemNative_FSync", SystemNative_FSync},
171 {"SystemNative_FTruncate", SystemNative_FTruncate},
172 {"SystemNative_FcntlCanGetSetPipeSz", SystemNative_FcntlCanGetSetPipeSz},
173 {"SystemNative_FcntlGetPipeSz", SystemNative_FcntlGetPipeSz},
174 {"SystemNative_FcntlSetCloseOnExec", SystemNative_FcntlSetCloseOnExec},
175 {"SystemNative_FcntlSetIsNonBlocking", SystemNative_FcntlSetIsNonBlocking},
176 {"SystemNative_FcntlSetPipeSz", SystemNative_FcntlSetPipeSz},
177 {"SystemNative_FnMatch", SystemNative_FnMatch},
178 {"SystemNative_GetLine", SystemNative_GetLine},
179 {"SystemNative_GetPeerID", SystemNative_GetPeerID},
180 {"SystemNative_GetReadDirRBufferSize", SystemNative_GetReadDirRBufferSize},
181 {"SystemNative_INotifyAddWatch", SystemNative_INotifyAddWatch},
182 {"SystemNative_INotifyInit", SystemNative_INotifyInit},
183 {"SystemNative_INotifyRemoveWatch", SystemNative_INotifyRemoveWatch},
184 {"SystemNative_LSeek", SystemNative_LSeek},
185 {"SystemNative_LStat2", SystemNative_LStat2},
186 {"SystemNative_Link", SystemNative_Link},
187 {"SystemNative_LockFileRegion", SystemNative_LockFileRegion},
188 {"SystemNative_MAdvise", SystemNative_MAdvise},
189 {"SystemNative_MLock", SystemNative_MLock},
190 {"SystemNative_MMap", SystemNative_MMap},
191 {"SystemNative_MProtect", SystemNative_MProtect},
192 {"SystemNative_MSync", SystemNative_MSync},
193 {"SystemNative_MUnlock", SystemNative_MUnlock},
194 {"SystemNative_MUnmap", SystemNative_MUnmap},
195 {"SystemNative_MkDir", SystemNative_MkDir},
196 {"SystemNative_MksTemps", SystemNative_MksTemps},
197 {"SystemNative_Open", SystemNative_Open},
198 {"SystemNative_OpenDir", SystemNative_OpenDir},
199 {"SystemNative_Pipe", SystemNative_Pipe},
200 {"SystemNative_Poll", SystemNative_Poll},
201 {"SystemNative_PosixFAdvise", SystemNative_PosixFAdvise},
202 {"SystemNative_Read", SystemNative_Read},
203 {"SystemNative_ReadDirR", SystemNative_ReadDirR},
204 {"SystemNative_ReadLink", SystemNative_ReadLink},
205 {"SystemNative_RealPath", SystemNative_RealPath},
206 {"SystemNative_Rename", SystemNative_Rename},
207 {"SystemNative_RmDir", SystemNative_RmDir},
208 {"SystemNative_ShmOpen", SystemNative_ShmOpen},
209 {"SystemNative_ShmUnlink", SystemNative_ShmUnlink},
210 {"SystemNative_Stat2", SystemNative_Stat2},
211 {"SystemNative_Sync", SystemNative_Sync},
212 {"SystemNative_SysConf", SystemNative_SysConf},
213 {"SystemNative_Unlink", SystemNative_Unlink},
214 {"SystemNative_Write", SystemNative_Write},
215 {"SystemNative_Accept", SystemNative_Accept},
216 {"SystemNative_Bind", SystemNative_Bind},
217 {"SystemNative_CloseSocketEventPort", SystemNative_CloseSocketEventPort},
218 {"SystemNative_Connect", SystemNative_Connect},
219 {"SystemNative_CreateSocketEventBuffer", SystemNative_CreateSocketEventBuffer},
220 {"SystemNative_CreateSocketEventPort", SystemNative_CreateSocketEventPort},
221 {"SystemNative_FreeHostEntry", SystemNative_FreeHostEntry},
222 {"SystemNative_FreeSocketEventBuffer", SystemNative_FreeSocketEventBuffer},
223 {"SystemNative_GetAddressFamily", SystemNative_GetAddressFamily},
224 {"SystemNative_GetAtOutOfBandMark", SystemNative_GetAtOutOfBandMark},
225 {"SystemNative_GetBytesAvailable", SystemNative_GetBytesAvailable},
226 {"SystemNative_GetControlMessageBufferSize", SystemNative_GetControlMessageBufferSize},
227 {"SystemNative_GetDomainName", SystemNative_GetDomainName},
228 {"SystemNative_GetDomainSocketSizes", SystemNative_GetDomainSocketSizes},
229 {"SystemNative_GetHostEntryForName", SystemNative_GetHostEntryForName},
230 {"SystemNative_GetHostName", SystemNative_GetHostName},
231 {"SystemNative_GetIPSocketAddressSizes", SystemNative_GetIPSocketAddressSizes},
232 {"SystemNative_GetIPv4Address", SystemNative_GetIPv4Address},
233 {"SystemNative_GetIPv4MulticastOption", SystemNative_GetIPv4MulticastOption},
234 {"SystemNative_GetIPv6Address", SystemNative_GetIPv6Address},
235 {"SystemNative_GetIPv6MulticastOption", SystemNative_GetIPv6MulticastOption},
236 {"SystemNative_GetLingerOption", SystemNative_GetLingerOption},
237 {"SystemNative_GetNameInfo", SystemNative_GetNameInfo},
238 {"SystemNative_GetNextIPAddress", SystemNative_GetNextIPAddress},
239 {"SystemNative_GetPeerName", SystemNative_GetPeerName},
240 {"SystemNative_GetPeerUserName", SystemNative_GetPeerUserName},
241 {"SystemNative_GetPort", SystemNative_GetPort},
242 {"SystemNative_GetSockName", SystemNative_GetSockName},
243 {"SystemNative_GetSockOpt", SystemNative_GetSockOpt},
244 {"SystemNative_GetSocketErrorOption", SystemNative_GetSocketErrorOption},
245 {"SystemNative_Listen", SystemNative_Listen},
246 {"SystemNative_PlatformSupportsDualModeIPv4PacketInfo", SystemNative_PlatformSupportsDualModeIPv4PacketInfo},
247 {"SystemNative_ReceiveMessage", SystemNative_ReceiveMessage},
248 {"SystemNative_SendFile", SystemNative_SendFile},
249 {"SystemNative_SendMessage", SystemNative_SendMessage},
250 {"SystemNative_SetAddressFamily", SystemNative_SetAddressFamily},
251 {"SystemNative_SetIPv4Address", SystemNative_SetIPv4Address},
252 {"SystemNative_SetIPv4MulticastOption", SystemNative_SetIPv4MulticastOption},
253 {"SystemNative_SetIPv6Address", SystemNative_SetIPv6Address},
254 {"SystemNative_SetIPv6MulticastOption", SystemNative_SetIPv6MulticastOption},
255 {"SystemNative_SetLingerOption", SystemNative_SetLingerOption},
256 {"SystemNative_SetPort", SystemNative_SetPort},
257 {"SystemNative_SetReceiveTimeout", SystemNative_SetReceiveTimeout},
258 {"SystemNative_SetSendTimeout", SystemNative_SetSendTimeout},
259 {"SystemNative_SetSockOpt", SystemNative_SetSockOpt},
260 {"SystemNative_Shutdown", SystemNative_Shutdown},
261 {"SystemNative_Socket", SystemNative_Socket},
262 {"SystemNative_TryChangeSocketEventRegistration", SystemNative_TryChangeSocketEventRegistration},
263 {"SystemNative_TryGetIPPacketInformation", SystemNative_TryGetIPPacketInformation},
264 {"SystemNative_WaitForSocketEvents", SystemNative_WaitForSocketEvents},
265 {"SystemNative_MapTcpState", SystemNative_MapTcpState},
266 {"SystemNative_GetNonCryptographicallySecureRandomBytes", SystemNative_GetNonCryptographicallySecureRandomBytes},
269 #ifdef CORE_BINDINGS
270 void core_initialize_internals ();
271 #endif
273 // Blazor specific custom routines - see dotnet_support.js for backing code
274 extern void* mono_wasm_invoke_js_marshalled (MonoString **exceptionMessage, void *asyncHandleLongPtr, MonoString *funcName, MonoString *argsJson);
275 extern void* mono_wasm_invoke_js_unmarshalled (MonoString **exceptionMessage, MonoString *funcName, void* arg0, void* arg1, void* arg2);
277 void mono_wasm_enable_debugging (void);
279 void mono_ee_interp_init (const char *opts);
280 void mono_marshal_ilgen_init (void);
281 void mono_method_builder_ilgen_init (void);
282 void mono_sgen_mono_ilgen_init (void);
283 void mono_icall_table_init (void);
284 void mono_aot_register_module (void **aot_info);
285 char *monoeg_g_getenv(const char *variable);
286 int monoeg_g_setenv(const char *variable, const char *value, int overwrite);
287 void mono_free (void*);
289 /* Not part of public headers */
290 #define MONO_ICALL_TABLE_CALLBACKS_VERSION 2
292 typedef struct {
293 int version;
294 void* (*lookup) (MonoMethod *method, char *classname, char *methodname, char *sigstart, uint8_t *uses_handles);
295 const char* (*lookup_icall_symbol) (void* func);
296 } MonoIcallTableCallbacks;
298 void
299 mono_install_icall_table_callbacks (MonoIcallTableCallbacks *cb);
301 int mono_regression_test_step (int verbose_level, char *image, char *method_name);
302 void mono_trace_init (void);
304 static char*
305 m_strdup (const char *str)
307 if (!str)
308 return NULL;
310 int len = strlen (str) + 1;
311 char *res = malloc (len);
312 memcpy (res, str, len);
313 return res;
316 static MonoDomain *root_domain;
318 static MonoString*
319 mono_wasm_invoke_js (MonoString *str, int *is_exception)
321 if (str == NULL)
322 return NULL;
324 char *native_val = mono_string_to_utf8 (str);
325 mono_unichar2 *native_res = (mono_unichar2*)EM_ASM_INT ({
326 var str = UTF8ToString ($0);
327 try {
328 var res = eval (str);
329 if (res === null || res == undefined)
330 return 0;
331 res = res.toString ();
332 setValue ($1, 0, "i32");
333 } catch (e) {
334 res = e.toString ();
335 setValue ($1, 1, "i32");
336 if (res === null || res === undefined)
337 res = "unknown exception";
339 var buff = Module._malloc((res.length + 1) * 2);
340 stringToUTF16 (res, buff, (res.length + 1) * 2);
341 return buff;
342 }, (int)native_val, is_exception);
344 mono_free (native_val);
346 if (native_res == NULL)
347 return NULL;
349 MonoString *res = mono_string_from_utf16 (native_res);
350 free (native_res);
351 return res;
354 static void
355 wasm_logger (const char *log_domain, const char *log_level, const char *message, mono_bool fatal, void *user_data)
357 if (fatal) {
358 EM_ASM(
359 var err = new Error();
360 console.log ("Stacktrace: \n");
361 console.log (err.stack);
364 fprintf (stderr, "%s", message);
366 abort ();
367 } else {
368 fprintf (stdout, "%s\n", message);
372 #ifdef DRIVER_GEN
373 #include "driver-gen.c"
374 #endif
376 typedef struct WasmAssembly_ WasmAssembly;
378 struct WasmAssembly_ {
379 MonoBundledAssembly assembly;
380 WasmAssembly *next;
383 static WasmAssembly *assemblies;
384 static int assembly_count;
386 EMSCRIPTEN_KEEPALIVE void
387 mono_wasm_add_assembly (const char *name, const unsigned char *data, unsigned int size)
389 int len = strlen (name);
390 if (!strcasecmp (".pdb", &name [len - 4])) {
391 char *new_name = m_strdup (name);
392 //FIXME handle debugging assemblies with .exe extension
393 strcpy (&new_name [len - 3], "dll");
394 mono_register_symfile_for_assembly (new_name, data, size);
395 return;
397 WasmAssembly *entry = (WasmAssembly *)malloc(sizeof (MonoBundledAssembly));
398 entry->assembly.name = m_strdup (name);
399 entry->assembly.data = data;
400 entry->assembly.size = size;
401 entry->next = assemblies;
402 assemblies = entry;
403 ++assembly_count;
406 EMSCRIPTEN_KEEPALIVE void
407 mono_wasm_setenv (const char *name, const char *value)
409 monoeg_g_setenv (strdup (name), strdup (value), 1);
412 static int sysnative_dl_handle;
414 static void*
415 wasm_dl_load (const char *name, int flags, char **err, void *user_data)
417 // FIXME: Add a general approach, this just makes System.IO work
418 if (!strcmp (name, "System.Native"))
419 return &sysnative_dl_handle;
420 return NULL;
423 static void*
424 wasm_dl_symbol (void *handle, const char *name, char **err, void *user_data)
426 if (handle == &sysnative_dl_handle) {
427 for (int i = 0; i < sizeof (sysnative_imports) / sizeof (sysnative_imports [0]); ++i)
428 if (!strcmp (sysnative_imports [i].name, name))
429 return sysnative_imports [i].func;
431 return NULL;
434 #if !defined(ENABLE_AOT) || defined(EE_MODE_LLVMONLY_INTERP)
435 #define NEED_INTERP 1
436 #ifndef LINK_ICALLS
437 // FIXME: llvm+interp mode needs this to call icalls
438 #define NEED_NORMAL_ICALL_TABLES 1
439 #endif
440 #endif
442 #ifdef LINK_ICALLS
444 #include "icall-table.h"
446 static int
447 compare_int (const void *k1, const void *k2)
449 return *(int*)k1 - *(int*)k2;
452 static void*
453 icall_table_lookup (MonoMethod *method, char *classname, char *methodname, char *sigstart, uint8_t *uses_handles)
455 uint32_t token = mono_method_get_token (method);
456 assert (token);
457 assert ((token & MONO_TOKEN_METHOD_DEF) == MONO_TOKEN_METHOD_DEF);
458 uint32_t token_idx = token - MONO_TOKEN_METHOD_DEF;
460 int *indexes = NULL;
461 int indexes_size = 0;
462 uint8_t *handles = NULL;
463 void **funcs = NULL;
465 *uses_handles = 0;
467 const char *image_name = mono_image_get_name (mono_class_get_image (mono_method_get_class (method)));
469 #ifdef ICALL_TABLE_mscorlib
470 if (!strcmp (image_name, "mscorlib")) {
471 indexes = mscorlib_icall_indexes;
472 indexes_size = sizeof (mscorlib_icall_indexes) / 4;
473 handles = mscorlib_icall_handles;
474 funcs = mscorlib_icall_funcs;
475 assert (sizeof (mscorlib_icall_indexes [0]) == 4);
477 #ifdef ICALL_TABLE_System
478 if (!strcmp (image_name, "System")) {
479 indexes = System_icall_indexes;
480 indexes_size = sizeof (System_icall_indexes) / 4;
481 handles = System_icall_handles;
482 funcs = System_icall_funcs;
484 #endif
485 assert (indexes);
487 void *p = bsearch (&token_idx, indexes, indexes_size, 4, compare_int);
488 if (!p) {
489 return NULL;
490 printf ("wasm: Unable to lookup icall: %s\n", mono_method_get_name (method));
491 exit (1);
494 uint32_t idx = (int*)p - indexes;
495 *uses_handles = handles [idx];
497 //printf ("ICALL: %s %x %d %d\n", methodname, token, idx, (int)(funcs [idx]));
499 return funcs [idx];
500 #endif
503 static const char*
504 icall_table_lookup_symbol (void *func)
506 assert (0);
507 return NULL;
510 #endif
512 void mono_initialize_internals ()
514 mono_add_internal_call ("WebAssembly.Runtime::InvokeJS", mono_wasm_invoke_js);
516 // Blazor specific custom routines - see dotnet_support.js for backing code
517 mono_add_internal_call ("WebAssembly.JSInterop.InternalCalls::InvokeJSMarshalled", mono_wasm_invoke_js_marshalled);
518 mono_add_internal_call ("WebAssembly.JSInterop.InternalCalls::InvokeJSUnmarshalled", mono_wasm_invoke_js_unmarshalled);
520 #ifdef CORE_BINDINGS
521 core_initialize_internals();
522 #endif
526 EMSCRIPTEN_KEEPALIVE void
527 mono_wasm_load_runtime (const char *managed_path, int enable_debugging)
529 monoeg_g_setenv ("MONO_LOG_LEVEL", "debug", 0);
530 monoeg_g_setenv ("MONO_LOG_MASK", "gc", 0);
532 mono_dl_fallback_register (wasm_dl_load, wasm_dl_symbol, NULL, NULL);
534 #ifdef ENABLE_AOT
535 // Defined in driver-gen.c
536 register_aot_modules ();
537 #ifdef EE_MODE_LLVMONLY_INTERP
538 mono_jit_set_aot_mode (MONO_AOT_MODE_LLVMONLY_INTERP);
539 #else
540 mono_jit_set_aot_mode (MONO_AOT_MODE_LLVMONLY);
541 #endif
542 #else
543 mono_jit_set_aot_mode (MONO_AOT_MODE_INTERP_LLVMONLY);
544 if (enable_debugging)
545 mono_wasm_enable_debugging ();
546 #endif
548 #ifdef LINK_ICALLS
549 /* Link in our own linked icall table */
550 MonoIcallTableCallbacks cb;
551 memset (&cb, 0, sizeof (MonoIcallTableCallbacks));
552 cb.version = MONO_ICALL_TABLE_CALLBACKS_VERSION;
553 cb.lookup = icall_table_lookup;
554 cb.lookup_icall_symbol = icall_table_lookup_symbol;
556 mono_install_icall_table_callbacks (&cb);
557 #endif
559 #ifdef NEED_NORMAL_ICALL_TABLES
560 mono_icall_table_init ();
561 #endif
562 #ifdef NEED_INTERP
563 mono_ee_interp_init ("");
564 mono_marshal_ilgen_init ();
565 mono_method_builder_ilgen_init ();
566 mono_sgen_mono_ilgen_init ();
567 #endif
569 if (assembly_count) {
570 MonoBundledAssembly **bundle_array = (MonoBundledAssembly **)calloc (1, sizeof (MonoBundledAssembly*) * (assembly_count + 1));
571 WasmAssembly *cur = assemblies;
572 bundle_array [assembly_count] = NULL;
573 int i = 0;
574 while (cur) {
575 bundle_array [i] = &cur->assembly;
576 cur = cur->next;
577 ++i;
579 mono_register_bundled_assemblies ((const MonoBundledAssembly**)bundle_array);
582 mono_trace_init ();
583 mono_trace_set_log_handler (wasm_logger, NULL);
584 root_domain = mono_jit_init_version ("mono", "v4.0.30319");
586 mono_initialize_internals();
589 EMSCRIPTEN_KEEPALIVE MonoAssembly*
590 mono_wasm_assembly_load (const char *name)
592 MonoImageOpenStatus status;
593 MonoAssemblyName* aname = mono_assembly_name_new (name);
594 if (!name)
595 return NULL;
597 MonoAssembly *res = mono_assembly_load (aname, NULL, &status);
598 mono_assembly_name_free (aname);
600 return res;
603 EMSCRIPTEN_KEEPALIVE MonoClass*
604 mono_wasm_assembly_find_class (MonoAssembly *assembly, const char *namespace, const char *name)
606 return mono_class_from_name (mono_assembly_get_image (assembly), namespace, name);
609 EMSCRIPTEN_KEEPALIVE MonoMethod*
610 mono_wasm_assembly_find_method (MonoClass *klass, const char *name, int arguments)
612 return mono_class_get_method_from_name (klass, name, arguments);
615 EMSCRIPTEN_KEEPALIVE MonoObject*
616 mono_wasm_invoke_method (MonoMethod *method, MonoObject *this_arg, void *params[], int* got_exception)
618 MonoObject *exc = NULL;
619 MonoObject *res = mono_runtime_invoke (method, this_arg, params, &exc);
620 *got_exception = 0;
622 if (exc) {
623 *got_exception = 1;
625 MonoObject *exc2 = NULL;
626 res = (MonoObject*)mono_object_to_string (exc, &exc2);
627 if (exc2)
628 res = (MonoObject*) mono_string_new (root_domain, "Exception Double Fault");
629 return res;
632 MonoMethodSignature *sig = mono_method_signature (method);
633 MonoType *type = mono_signature_get_return_type (sig);
634 // If the method return type is void return null
635 // This gets around a memory access crash when the result return a value when
636 // a void method is invoked.
637 if (mono_type_get_type (type) == MONO_TYPE_VOID)
638 return NULL;
640 return res;
643 EMSCRIPTEN_KEEPALIVE MonoMethod*
644 mono_wasm_assembly_get_entry_point (MonoAssembly *assembly)
646 MonoImage *image;
647 MonoMethod *method;
649 image = mono_assembly_get_image (assembly);
650 uint32_t entry = mono_image_get_entry_point (image);
651 if (!entry)
652 return NULL;
654 return mono_get_method (image, entry, NULL);
657 EMSCRIPTEN_KEEPALIVE char *
658 mono_wasm_string_get_utf8 (MonoString *str)
660 return mono_string_to_utf8 (str); //XXX JS is responsible for freeing this
663 EMSCRIPTEN_KEEPALIVE MonoString *
664 mono_wasm_string_from_js (const char *str)
666 return mono_string_new (root_domain, str);
669 static int
670 class_is_task (MonoClass *klass)
672 if (!strcmp ("System.Threading.Tasks", mono_class_get_namespace (klass)) &&
673 (!strcmp ("Task", mono_class_get_name (klass)) || !strcmp ("Task`1", mono_class_get_name (klass))))
674 return 1;
676 return 0;
679 #define MARSHAL_TYPE_INT 1
680 #define MARSHAL_TYPE_FP 2
681 #define MARSHAL_TYPE_STRING 3
682 #define MARSHAL_TYPE_VT 4
683 #define MARSHAL_TYPE_DELEGATE 5
684 #define MARSHAL_TYPE_TASK 6
685 #define MARSHAL_TYPE_OBJECT 7
686 #define MARSHAL_TYPE_BOOL 8
687 #define MARSHAL_TYPE_ENUM 9
689 // typed array marshalling
690 #define MARSHAL_ARRAY_BYTE 11
691 #define MARSHAL_ARRAY_UBYTE 12
692 #define MARSHAL_ARRAY_SHORT 13
693 #define MARSHAL_ARRAY_USHORT 14
694 #define MARSHAL_ARRAY_INT 15
695 #define MARSHAL_ARRAY_UINT 16
696 #define MARSHAL_ARRAY_FLOAT 17
697 #define MARSHAL_ARRAY_DOUBLE 18
699 EMSCRIPTEN_KEEPALIVE int
700 mono_wasm_get_obj_type (MonoObject *obj)
702 if (!obj)
703 return 0;
704 MonoClass *klass = mono_object_get_class (obj);
705 MonoType *type = mono_class_get_type (klass);
707 switch (mono_type_get_type (type)) {
708 // case MONO_TYPE_CHAR: prob should be done not as a number?
709 case MONO_TYPE_BOOLEAN:
710 return MARSHAL_TYPE_BOOL;
711 case MONO_TYPE_I1:
712 case MONO_TYPE_U1:
713 case MONO_TYPE_I2:
714 case MONO_TYPE_U2:
715 case MONO_TYPE_I4:
716 case MONO_TYPE_U4:
717 case MONO_TYPE_I8:
718 case MONO_TYPE_U8:
719 return MARSHAL_TYPE_INT;
720 case MONO_TYPE_R4:
721 case MONO_TYPE_R8:
722 return MARSHAL_TYPE_FP;
723 case MONO_TYPE_STRING:
724 return MARSHAL_TYPE_STRING;
725 case MONO_TYPE_SZARRAY: { // simple zero based one-dim-array
726 MonoClass *eklass = mono_class_get_element_class(klass);
727 MonoType *etype = mono_class_get_type (eklass);
729 switch (mono_type_get_type (etype)) {
730 case MONO_TYPE_U1:
731 return MARSHAL_ARRAY_UBYTE;
732 case MONO_TYPE_I1:
733 return MARSHAL_ARRAY_BYTE;
734 case MONO_TYPE_U2:
735 return MARSHAL_ARRAY_USHORT;
736 case MONO_TYPE_I2:
737 return MARSHAL_ARRAY_SHORT;
738 case MONO_TYPE_U4:
739 return MARSHAL_ARRAY_UINT;
740 case MONO_TYPE_I4:
741 return MARSHAL_ARRAY_INT;
742 case MONO_TYPE_R4:
743 return MARSHAL_ARRAY_FLOAT;
744 case MONO_TYPE_R8:
745 return MARSHAL_ARRAY_DOUBLE;
746 default:
747 return MARSHAL_TYPE_OBJECT;
750 default:
751 if (mono_class_is_enum (klass))
752 return MARSHAL_TYPE_ENUM;
753 if (!mono_type_is_reference (type)) //vt
754 return MARSHAL_TYPE_VT;
755 if (mono_class_is_delegate (klass))
756 return MARSHAL_TYPE_DELEGATE;
757 if (class_is_task(klass))
758 return MARSHAL_TYPE_TASK;
760 return MARSHAL_TYPE_OBJECT;
765 EMSCRIPTEN_KEEPALIVE int
766 mono_unbox_int (MonoObject *obj)
768 if (!obj)
769 return 0;
770 MonoType *type = mono_class_get_type (mono_object_get_class(obj));
772 void *ptr = mono_object_unbox (obj);
773 switch (mono_type_get_type (type)) {
774 case MONO_TYPE_I1:
775 case MONO_TYPE_BOOLEAN:
776 return *(signed char*)ptr;
777 case MONO_TYPE_U1:
778 return *(unsigned char*)ptr;
779 case MONO_TYPE_I2:
780 return *(short*)ptr;
781 case MONO_TYPE_U2:
782 return *(unsigned short*)ptr;
783 case MONO_TYPE_I4:
784 return *(int*)ptr;
785 case MONO_TYPE_U4:
786 return *(unsigned int*)ptr;
787 // WASM doesn't support returning longs to JS
788 // case MONO_TYPE_I8:
789 // case MONO_TYPE_U8:
790 default:
791 printf ("Invalid type %d to mono_unbox_int\n", mono_type_get_type (type));
792 return 0;
796 EMSCRIPTEN_KEEPALIVE double
797 mono_wasm_unbox_float (MonoObject *obj)
799 if (!obj)
800 return 0;
801 MonoType *type = mono_class_get_type (mono_object_get_class(obj));
803 void *ptr = mono_object_unbox (obj);
804 switch (mono_type_get_type (type)) {
805 case MONO_TYPE_R4:
806 return *(float*)ptr;
807 case MONO_TYPE_R8:
808 return *(double*)ptr;
809 default:
810 printf ("Invalid type %d to mono_wasm_unbox_float\n", mono_type_get_type (type));
811 return 0;
815 EMSCRIPTEN_KEEPALIVE int
816 mono_wasm_array_length (MonoArray *array)
818 return mono_array_length (array);
821 EMSCRIPTEN_KEEPALIVE MonoObject*
822 mono_wasm_array_get (MonoArray *array, int idx)
824 return mono_array_get (array, MonoObject*, idx);
827 EMSCRIPTEN_KEEPALIVE MonoArray*
828 mono_wasm_obj_array_new (int size)
830 return mono_array_new (root_domain, mono_get_object_class (), size);
833 EMSCRIPTEN_KEEPALIVE void
834 mono_wasm_obj_array_set (MonoArray *array, int idx, MonoObject *obj)
836 mono_array_setref (array, idx, obj);
839 EMSCRIPTEN_KEEPALIVE MonoArray*
840 mono_wasm_string_array_new (int size)
842 return mono_array_new (root_domain, mono_get_string_class (), size);
845 EMSCRIPTEN_KEEPALIVE int
846 mono_wasm_exec_regression (int verbose_level, char *image)
848 return mono_regression_test_step (verbose_level, image, NULL) ? 0 : 1;
851 EMSCRIPTEN_KEEPALIVE int
852 mono_wasm_exit (int exit_code)
854 exit (exit_code);
857 EMSCRIPTEN_KEEPALIVE void
858 mono_wasm_set_main_args (int argc, char* argv[])
860 mono_runtime_set_main_args (argc, argv);
863 EMSCRIPTEN_KEEPALIVE int
864 mono_wasm_strdup (const char *s)
866 return (int)strdup (s);