[sdks] One more update to get XA PR builds working on Linux (#10853)
[mono-project.git] / sdks / wasm / driver.c
blobe86e3d348469c8ee3409d83a4ae18bc8b5e64621
1 #include <emscripten.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
7 typedef enum {
8 /* Disables AOT mode */
9 MONO_AOT_MODE_NONE,
10 /* Enables normal AOT mode, equivalent to mono_jit_set_aot_only (false) */
11 MONO_AOT_MODE_NORMAL,
12 /* Enables hybrid AOT mode, JIT can still be used for wrappers */
13 MONO_AOT_MODE_HYBRID,
14 /* Enables full AOT mode, JIT is disabled and not allowed,
15 * equivalent to mono_jit_set_aot_only (true) */
16 MONO_AOT_MODE_FULL,
17 /* Same as full, but use only llvm compiled code */
18 MONO_AOT_MODE_LLVMONLY,
19 /* Uses Interpreter, JIT is disabled and not allowed,
20 * equivalent to "--full-aot --interpreter" */
21 MONO_AOT_MODE_INTERP,
22 /* Same as INTERP, but use only llvm compiled code */
23 MONO_AOT_MODE_INTERP_LLVMONLY,
24 } MonoAotMode;
26 typedef enum {
27 MONO_TYPE_END = 0x00, /* End of List */
28 MONO_TYPE_VOID = 0x01,
29 MONO_TYPE_BOOLEAN = 0x02,
30 MONO_TYPE_CHAR = 0x03,
31 MONO_TYPE_I1 = 0x04,
32 MONO_TYPE_U1 = 0x05,
33 MONO_TYPE_I2 = 0x06,
34 MONO_TYPE_U2 = 0x07,
35 MONO_TYPE_I4 = 0x08,
36 MONO_TYPE_U4 = 0x09,
37 MONO_TYPE_I8 = 0x0a,
38 MONO_TYPE_U8 = 0x0b,
39 MONO_TYPE_R4 = 0x0c,
40 MONO_TYPE_R8 = 0x0d,
41 MONO_TYPE_STRING = 0x0e,
42 MONO_TYPE_PTR = 0x0f, /* arg: <type> token */
43 MONO_TYPE_BYREF = 0x10, /* arg: <type> token */
44 MONO_TYPE_VALUETYPE = 0x11, /* arg: <type> token */
45 MONO_TYPE_CLASS = 0x12, /* arg: <type> token */
46 MONO_TYPE_VAR = 0x13, /* number */
47 MONO_TYPE_ARRAY = 0x14, /* type, rank, boundsCount, bound1, loCount, lo1 */
48 MONO_TYPE_GENERICINST= 0x15, /* <type> <type-arg-count> <type-1> \x{2026} <type-n> */
49 MONO_TYPE_TYPEDBYREF = 0x16,
50 MONO_TYPE_I = 0x18,
51 MONO_TYPE_U = 0x19,
52 MONO_TYPE_FNPTR = 0x1b, /* arg: full method signature */
53 MONO_TYPE_OBJECT = 0x1c,
54 MONO_TYPE_SZARRAY = 0x1d, /* 0-based one-dim-array */
55 MONO_TYPE_MVAR = 0x1e, /* number */
56 MONO_TYPE_CMOD_REQD = 0x1f, /* arg: typedef or typeref token */
57 MONO_TYPE_CMOD_OPT = 0x20, /* optional arg: typedef or typref token */
58 MONO_TYPE_INTERNAL = 0x21, /* CLR internal type */
60 MONO_TYPE_MODIFIER = 0x40, /* Or with the following types */
61 MONO_TYPE_SENTINEL = 0x41, /* Sentinel for varargs method signature */
62 MONO_TYPE_PINNED = 0x45, /* Local var that points to pinned object */
64 MONO_TYPE_ENUM = 0x55 /* an enumeration */
65 } MonoTypeEnum;
67 typedef enum {
68 MONO_IMAGE_OK,
69 MONO_IMAGE_ERROR_ERRNO,
70 MONO_IMAGE_MISSING_ASSEMBLYREF,
71 MONO_IMAGE_IMAGE_INVALID
72 } MonoImageOpenStatus;
74 typedef struct MonoType_ MonoType;
75 typedef struct MonoDomain_ MonoDomain;
76 typedef struct MonoAssembly_ MonoAssembly;
77 typedef struct MonoMethod_ MonoMethod;
78 typedef struct MonoException_ MonoException;
79 typedef struct MonoString_ MonoString;
80 typedef struct MonoClass_ MonoClass;
81 typedef struct MonoImage_ MonoImage;
82 typedef struct MonoObject_ MonoObject;
83 typedef struct MonoArray_ MonoArray;
84 typedef struct MonoThread_ MonoThread;
85 typedef struct _MonoAssemblyName MonoAssemblyName;
88 //JS funcs
89 extern MonoObject* mono_wasm_invoke_js_with_args (int js_handle, MonoString *method, MonoArray *args, int *is_exception);
90 extern MonoObject* mono_wasm_get_object_property (int js_handle, MonoString *method, int *is_exception);
91 extern MonoObject* mono_wasm_set_object_property (int js_handle, MonoString *method, MonoObject *value, int createIfNotExist, int hasOwnProperty, int *is_exception);
92 extern MonoObject* mono_wasm_get_global_object (MonoString *globalName, int *is_exception);
94 // Blazor specific custom routines - see dotnet_support.js for backing code
95 extern void* mono_wasm_invoke_js_marshalled (MonoString **exceptionMessage, void *asyncHandleLongPtr, MonoString *funcName, MonoString *argsJson);
96 extern void* mono_wasm_invoke_js_unmarshalled (MonoString **exceptionMessage, MonoString *funcName, void* arg0, void* arg1, void* arg2);
97 void mono_aot_register_module (void **aot_info);
98 void mono_jit_set_aot_mode (MonoAotMode mode);
99 MonoDomain* mono_jit_init_version (const char *root_domain_name, const char *runtime_version);
100 void mono_ee_interp_init (const char *opts);
101 void mono_marshal_ilgen_init (void);
102 void mono_method_builder_ilgen_init (void);
103 void mono_sgen_mono_ilgen_init (void);
104 void mono_icall_table_init (void);
105 MonoAssembly* mono_assembly_open (const char *filename, MonoImageOpenStatus *status);
106 int mono_jit_exec (MonoDomain *domain, MonoAssembly *assembly, int argc, char *argv[]);
107 void mono_set_assemblies_path (const char* path);
108 int monoeg_g_setenv(const char *variable, const char *value, int overwrite);
109 void mono_free (void*);
110 MonoString* mono_string_new (MonoDomain *domain, const char *text);
111 MonoDomain* mono_domain_get (void);
112 MonoClass* mono_class_from_name (MonoImage *image, const char* name_space, const char *name);
113 MonoMethod* mono_class_get_method_from_name (MonoClass *klass, const char *name, int param_count);
114 MonoType* mono_class_get_type (MonoClass *klass);
115 MonoClass* mono_object_get_class (MonoObject *obj);
116 int mono_type_get_type (MonoType *type);
117 int mono_type_is_reference (MonoType *type);
119 MonoString* mono_object_to_string (MonoObject *obj, MonoObject **exc);//FIXME Use MonoError variant
120 char* mono_string_to_utf8 (MonoString *string_obj);
121 MonoObject* mono_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObject **exc);
122 void* mono_object_unbox (MonoObject *obj);
124 MonoImage* mono_assembly_get_image (MonoAssembly *assembly);
125 MonoAssembly* mono_assembly_load (MonoAssemblyName *aname, const char *basedir, MonoImageOpenStatus *status);
127 MonoAssemblyName* mono_assembly_name_new (const char *name);
128 void mono_assembly_name_free (MonoAssemblyName *aname);
129 const char* mono_image_get_name (MonoImage *image);
130 MonoString* mono_string_new (MonoDomain *domain, const char *text);
131 void mono_add_internal_call (const char *name, const void* method);
132 MonoString * mono_string_from_utf16 (char *data);
133 MonoString* mono_string_new (MonoDomain *domain, const char *text);
134 void mono_wasm_enable_debugging (void);
135 MonoArray* mono_array_new (MonoDomain *domain, MonoClass *eclass, int n);
136 MonoClass* mono_get_object_class (void);
137 int mono_class_is_delegate (MonoClass* klass);
138 const char* mono_class_get_name (MonoClass *klass);
139 const char* mono_class_get_namespace (MonoClass *klass);
140 MonoClass* mono_get_byte_class (void);
141 MonoClass* mono_get_sbyte_class (void);
142 MonoClass* mono_get_int16_class (void);
143 MonoClass* mono_get_uint16_class (void);
144 MonoClass* mono_get_int32_class (void);
145 MonoClass* mono_get_uint32_class (void);
146 MonoClass* mono_get_single_class (void);
147 MonoClass* mono_get_double_class (void);
148 MonoClass* mono_class_get_element_class(MonoClass *klass);
149 int mono_regression_test_step (int verbose_level, char *image, char *method_name);
152 #define mono_array_get(array,type,index) ( *(type*)mono_array_addr ((array), type, (index)) )
153 #define mono_array_addr(array,type,index) ((type*)(void*) mono_array_addr_with_size (array, sizeof (type), index))
154 #define mono_array_setref(array,index,value) \
155 do { \
156 void **__p = (void **) mono_array_addr ((array), void*, (index)); \
157 mono_gc_wbarrier_set_arrayref ((array), __p, (MonoObject*)(value)); \
158 /* *__p = (value);*/ \
159 } while (0)
162 char* mono_array_addr_with_size (MonoArray *array, int size, int idx);
163 int mono_array_length (MonoArray *array);
164 int mono_array_element_size(MonoClass *klass);
165 void mono_gc_wbarrier_set_arrayref (MonoArray *arr, void* slot_ptr, MonoObject* value);
167 typedef struct {
168 const char *name;
169 const unsigned char *data;
170 unsigned int size;
171 } MonoBundledAssembly;
173 void mono_register_bundled_assemblies (const MonoBundledAssembly **assemblies);
175 static char*
176 m_strdup (const char *str)
178 if (!str)
179 return NULL;
181 int len = strlen (str) + 1;
182 char *res = malloc (len);
183 memcpy (res, str, len);
184 return res;
187 static MonoDomain *root_domain;
189 static MonoString*
190 mono_wasm_invoke_js (MonoString *str, int *is_exception)
192 if (str == NULL)
193 return NULL;
195 char *native_val = mono_string_to_utf8 (str);
196 char *native_res = (char*)EM_ASM_INT ({
197 var str = UTF8ToString ($0);
198 try {
199 var res = eval (str);
200 if (res === null || res == undefined)
201 return 0;
202 res = res.toString ();
203 setValue ($1, 0, "i32");
204 } catch (e) {
205 res = e.toString ();
206 setValue ($1, 1, "i32");
207 if (res === null || res === undefined)
208 res = "unknown exception";
210 var buff = Module._malloc((res.length + 1) * 2);
211 stringToUTF16 (res, buff, (res.length + 1) * 2);
212 return buff;
213 }, (int)native_val, is_exception);
215 mono_free (native_val);
217 if (native_res == NULL)
218 return NULL;
220 MonoString *res = mono_string_from_utf16 (native_res);
221 free (native_res);
222 return res;
225 #ifdef ENABLE_AOT
226 #include "driver-gen.c"
227 #endif
229 typedef struct WasmAssembly_ WasmAssembly;
231 struct WasmAssembly_ {
232 MonoBundledAssembly assembly;
233 WasmAssembly *next;
236 static WasmAssembly *assemblies;
237 static int assembly_count;
239 EMSCRIPTEN_KEEPALIVE void
240 mono_wasm_add_assembly (const char *name, const unsigned char *data, unsigned int size)
242 WasmAssembly *entry = (WasmAssembly *)malloc(sizeof (MonoBundledAssembly));
243 entry->assembly.name = m_strdup (name);
244 entry->assembly.data = data;
245 entry->assembly.size = size;
246 entry->next = assemblies;
247 assemblies = entry;
248 ++assembly_count;
251 EMSCRIPTEN_KEEPALIVE void
252 mono_wasm_load_runtime (const char *managed_path, int enable_debugging)
254 monoeg_g_setenv ("MONO_LOG_LEVEL", "debug", 1);
255 monoeg_g_setenv ("MONO_LOG_MASK", "gc", 1);
257 #ifdef ENABLE_AOT
258 // Defined in driver-gen.c
259 register_aot_modules ();
260 mono_jit_set_aot_mode (MONO_AOT_MODE_LLVMONLY);
261 #else
262 mono_jit_set_aot_mode (MONO_AOT_MODE_INTERP_LLVMONLY);
263 if (enable_debugging)
264 mono_wasm_enable_debugging ();
265 #endif
267 #ifndef ENABLE_AOT
268 mono_ee_interp_init ("");
269 mono_marshal_ilgen_init ();
270 mono_method_builder_ilgen_init ();
271 mono_sgen_mono_ilgen_init ();
272 #endif
273 mono_icall_table_init ();
275 if (assembly_count) {
276 MonoBundledAssembly **bundle_array = (MonoBundledAssembly **)calloc (1, sizeof (MonoBundledAssembly*) * (assembly_count + 1));
277 WasmAssembly *cur = assemblies;
278 bundle_array [assembly_count] = NULL;
279 int i = 0;
280 while (cur) {
281 bundle_array [i] = &cur->assembly;
282 cur = cur->next;
283 ++i;
285 mono_register_bundled_assemblies ((const MonoBundledAssembly**)bundle_array);
288 mono_set_assemblies_path (m_strdup (managed_path));
289 root_domain = mono_jit_init_version ("mono", "v4.0.30319");
291 mono_add_internal_call ("WebAssembly.Runtime::InvokeJS", mono_wasm_invoke_js);
292 mono_add_internal_call ("WebAssembly.Runtime::InvokeJSWithArgs", mono_wasm_invoke_js_with_args);
293 mono_add_internal_call ("WebAssembly.Runtime::GetObjectProperty", mono_wasm_get_object_property);
294 mono_add_internal_call ("WebAssembly.Runtime::SetObjectProperty", mono_wasm_set_object_property);
295 mono_add_internal_call ("WebAssembly.Runtime::GetGlobalObject", mono_wasm_get_global_object);
297 // Blazor specific custom routines - see dotnet_support.js for backing code
298 mono_add_internal_call ("WebAssembly.JSInterop.InternalCalls::InvokeJSMarshalled", mono_wasm_invoke_js_marshalled);
299 mono_add_internal_call ("WebAssembly.JSInterop.InternalCalls::InvokeJSUnmarshalled", mono_wasm_invoke_js_unmarshalled);
303 EMSCRIPTEN_KEEPALIVE MonoAssembly*
304 mono_wasm_assembly_load (const char *name)
306 MonoImageOpenStatus status;
307 MonoAssemblyName* aname = mono_assembly_name_new (name);
308 if (!name)
309 return NULL;
311 MonoAssembly *res = mono_assembly_load (aname, NULL, &status);
312 mono_assembly_name_free (aname);
314 return res;
317 EMSCRIPTEN_KEEPALIVE MonoClass*
318 mono_wasm_assembly_find_class (MonoAssembly *assembly, const char *namespace, const char *name)
320 return mono_class_from_name (mono_assembly_get_image (assembly), namespace, name);
323 EMSCRIPTEN_KEEPALIVE MonoMethod*
324 mono_wasm_assembly_find_method (MonoClass *klass, const char *name, int arguments)
326 return mono_class_get_method_from_name (klass, name, arguments);
329 EMSCRIPTEN_KEEPALIVE MonoObject*
330 mono_wasm_invoke_method (MonoMethod *method, MonoObject *this_arg, void *params[], int* got_exception)
332 MonoObject *exc = NULL;
333 MonoObject *res = mono_runtime_invoke (method, this_arg, params, &exc);
334 *got_exception = 0;
336 if (exc) {
337 *got_exception = 1;
339 MonoObject *exc2 = NULL;
340 res = (MonoObject*)mono_object_to_string (exc, &exc2);
341 if (exc2)
342 res = (MonoObject*) mono_string_new (root_domain, "Exception Double Fault");
343 return res;
346 return res;
349 EMSCRIPTEN_KEEPALIVE char *
350 mono_wasm_string_get_utf8 (MonoString *str)
352 return mono_string_to_utf8 (str); //XXX JS is responsible for freeing this
355 EMSCRIPTEN_KEEPALIVE MonoString *
356 mono_wasm_string_from_js (const char *str)
358 return mono_string_new (root_domain, str);
362 static int
363 class_is_task (MonoClass *klass)
365 if (!strcmp ("System.Threading.Tasks", mono_class_get_namespace (klass)) &&
366 (!strcmp ("Task", mono_class_get_name (klass)) || !strcmp ("Task`1", mono_class_get_name (klass))))
367 return 1;
369 return 0;
372 #define MARSHAL_TYPE_INT 1
373 #define MARSHAL_TYPE_FP 2
374 #define MARSHAL_TYPE_STRING 3
375 #define MARSHAL_TYPE_VT 4
376 #define MARSHAL_TYPE_DELEGATE 5
377 #define MARSHAL_TYPE_TASK 6
378 #define MARSHAL_TYPE_OBJECT 7
379 #define MARSHAL_TYPE_BOOL 8
381 // typed array marshalling
382 #define MARSHAL_ARRAY_BYTE 11
383 #define MARSHAL_ARRAY_UBYTE 12
384 #define MARSHAL_ARRAY_SHORT 13
385 #define MARSHAL_ARRAY_USHORT 14
386 #define MARSHAL_ARRAY_INT 15
387 #define MARSHAL_ARRAY_UINT 16
388 #define MARSHAL_ARRAY_FLOAT 17
389 #define MARSHAL_ARRAY_DOUBLE 18
391 EMSCRIPTEN_KEEPALIVE int
392 mono_wasm_get_obj_type (MonoObject *obj)
394 if (!obj)
395 return 0;
396 MonoClass *klass = mono_object_get_class (obj);
397 MonoType *type = mono_class_get_type (klass);
399 switch (mono_type_get_type (type)) {
400 // case MONO_TYPE_CHAR: prob should be done not as a number?
401 case MONO_TYPE_BOOLEAN:
402 return MARSHAL_TYPE_BOOL;
403 case MONO_TYPE_I1:
404 case MONO_TYPE_U1:
405 case MONO_TYPE_I2:
406 case MONO_TYPE_U2:
407 case MONO_TYPE_I4:
408 case MONO_TYPE_U4:
409 case MONO_TYPE_I8:
410 case MONO_TYPE_U8:
411 return MARSHAL_TYPE_INT;
412 case MONO_TYPE_R4:
413 case MONO_TYPE_R8:
414 return MARSHAL_TYPE_FP;
415 case MONO_TYPE_STRING:
416 return MARSHAL_TYPE_STRING;
417 case MONO_TYPE_SZARRAY: { // simple zero based one-dim-array
418 MonoClass *eklass = mono_class_get_element_class(klass);
419 MonoType *etype = mono_class_get_type (eklass);
421 switch (mono_type_get_type (etype)) {
422 case MONO_TYPE_U1:
423 return MARSHAL_ARRAY_UBYTE;
424 case MONO_TYPE_I1:
425 return MARSHAL_ARRAY_BYTE;
426 case MONO_TYPE_U2:
427 return MARSHAL_ARRAY_USHORT;
428 case MONO_TYPE_I2:
429 return MARSHAL_ARRAY_SHORT;
430 case MONO_TYPE_U4:
431 return MARSHAL_ARRAY_UINT;
432 case MONO_TYPE_I4:
433 return MARSHAL_ARRAY_INT;
434 case MONO_TYPE_R4:
435 return MARSHAL_ARRAY_FLOAT;
436 case MONO_TYPE_R8:
437 return MARSHAL_ARRAY_DOUBLE;
438 default:
439 return MARSHAL_TYPE_OBJECT;
442 default:
443 if (!mono_type_is_reference (type)) //vt
444 return MARSHAL_TYPE_VT;
445 if (mono_class_is_delegate (klass))
446 return MARSHAL_TYPE_DELEGATE;
447 if (class_is_task(klass))
448 return MARSHAL_TYPE_TASK;
450 return MARSHAL_TYPE_OBJECT;
455 EMSCRIPTEN_KEEPALIVE int
456 mono_unbox_int (MonoObject *obj)
458 if (!obj)
459 return 0;
460 MonoType *type = mono_class_get_type (mono_object_get_class(obj));
462 void *ptr = mono_object_unbox (obj);
463 switch (mono_type_get_type (type)) {
464 case MONO_TYPE_I1:
465 case MONO_TYPE_BOOLEAN:
466 return *(signed char*)ptr;
467 case MONO_TYPE_U1:
468 return *(unsigned char*)ptr;
469 case MONO_TYPE_I2:
470 return *(short*)ptr;
471 case MONO_TYPE_U2:
472 return *(unsigned short*)ptr;
473 case MONO_TYPE_I4:
474 return *(int*)ptr;
475 case MONO_TYPE_U4:
476 return *(unsigned int*)ptr;
477 // WASM doesn't support returning longs to JS
478 // case MONO_TYPE_I8:
479 // case MONO_TYPE_U8:
480 default:
481 printf ("Invalid type %d to mono_unbox_int\n", mono_type_get_type (type));
482 return 0;
486 EMSCRIPTEN_KEEPALIVE double
487 mono_wasm_unbox_float (MonoObject *obj)
489 if (!obj)
490 return 0;
491 MonoType *type = mono_class_get_type (mono_object_get_class(obj));
493 void *ptr = mono_object_unbox (obj);
494 switch (mono_type_get_type (type)) {
495 case MONO_TYPE_R4:
496 return *(float*)ptr;
497 case MONO_TYPE_R8:
498 return *(double*)ptr;
499 default:
500 printf ("Invalid type %d to mono_wasm_unbox_float\n", mono_type_get_type (type));
501 return 0;
505 EMSCRIPTEN_KEEPALIVE int
506 mono_wasm_array_length (MonoArray *array)
508 return mono_array_length (array);
511 EMSCRIPTEN_KEEPALIVE MonoObject*
512 mono_wasm_array_get (MonoArray *array, int idx)
514 return mono_array_get (array, MonoObject*, idx);
517 EMSCRIPTEN_KEEPALIVE MonoArray*
518 mono_wasm_obj_array_new (int size)
520 return mono_array_new (root_domain, mono_get_object_class (), size);
523 EMSCRIPTEN_KEEPALIVE void
524 mono_wasm_obj_array_set (MonoArray *array, int idx, MonoObject *obj)
526 mono_array_setref (array, idx, obj);
529 // Int8Array | int8_t | byte or SByte (signed byte)
530 // Uint8Array | uint8_t | byte or Byte (unsigned byte)
531 // Uint8ClampedArray| uint8_t | byte or Byte (unsigned byte)
532 // Int16Array | int16_t | short (signed short)
533 // Uint16Array | uint16_t | ushort (unsigned short)
534 // Int32Array | int32_t | int (signed integer)
535 // Uint32Array | uint32_t | uint (unsigned integer)
536 // Float32Array | float | float
537 // Float64Array | double | double
539 EMSCRIPTEN_KEEPALIVE MonoArray*
540 mono_wasm_typed_array_new (char *arr, int length, int size, int type)
542 MonoClass *typeClass = mono_get_byte_class(); // default is Byte
543 switch (type) {
544 case MARSHAL_ARRAY_BYTE:
545 typeClass = mono_get_sbyte_class();
546 break;
547 case MARSHAL_ARRAY_SHORT:
548 typeClass = mono_get_int16_class();
549 break;
550 case MARSHAL_ARRAY_USHORT:
551 typeClass = mono_get_uint16_class();
552 break;
553 case MARSHAL_ARRAY_INT:
554 typeClass = mono_get_int32_class();
555 break;
556 case MARSHAL_ARRAY_UINT:
557 typeClass = mono_get_uint32_class();
558 break;
559 case MARSHAL_ARRAY_FLOAT:
560 typeClass = mono_get_single_class();
561 break;
562 case MARSHAL_ARRAY_DOUBLE:
563 typeClass = mono_get_double_class();
564 break;
567 MonoArray *buffer;
569 buffer = mono_array_new (root_domain, typeClass, length);
570 memcpy(mono_array_addr_with_size(buffer, sizeof(char), 0), arr, length * size);
572 return buffer;
576 EMSCRIPTEN_KEEPALIVE void
577 mono_wasm_array_to_heap (MonoArray *src, char *dest)
579 int element_size;
580 void *source_addr;
581 int arr_length;
583 element_size = mono_array_element_size ( mono_object_get_class((MonoObject*)src));
584 //DBG("mono_wasm_to_heap element size %i / length %i\n",element_size, mono_array_length(src));
586 // get our src address
587 source_addr = mono_array_addr_with_size (src, element_size, 0);
588 // copy the array memory to heap via ptr dest
589 memcpy (dest, source_addr, mono_array_length(src) * element_size);
592 EMSCRIPTEN_KEEPALIVE int
593 mono_wasm_exec_regression (int verbose_level, char *image)
595 return mono_regression_test_step (verbose_level, image, NULL) ? 0 : 1;