2 #include "mini-runtime.h"
3 #include <mono/metadata/mono-debug.h>
4 #include <mono/metadata/assembly.h>
5 #include <mono/metadata/metadata.h>
6 #include <mono/metadata/loader-internals.h>
7 #include <mono/metadata/icall-internals.h>
8 #include <mono/metadata/seq-points-data.h>
9 #include <mono/mini/aot-runtime.h>
10 #include <mono/mini/seq-points.h>
12 //XXX This is dirty, extend ee.h to support extracting info from MonoInterpFrameHandle
13 #include <mono/mini/interp/interp-internals.h>
20 //FIXME figure out if we need to distingush between i,l,f,d types
23 ArgValuetypeAddrOnStack
,
25 ArgValuetypeAddrInIReg
,
30 ArgStorage storage
: 8;
42 get_storage (MonoType
*type
, gboolean is_return
)
55 case MONO_TYPE_OBJECT
:
68 case MONO_TYPE_GENERICINST
:
69 if (!mono_type_generic_inst_is_valuetype (type
))
72 if (mini_is_gsharedvt_type (type
)) {
73 return ArgGsharedVTOnStack
;
76 case MONO_TYPE_VALUETYPE
:
77 case MONO_TYPE_TYPEDBYREF
: {
78 return is_return
? ArgValuetypeAddrInIReg
: ArgValuetypeAddrOnStack
;
83 g_assert (mini_is_gsharedvt_type (type
));
84 return ArgGsharedVTOnStack
;
90 g_error ("Can't handle as return value 0x%x", type
->type
);
96 get_call_info (MonoMemPool
*mp
, MonoMethodSignature
*sig
)
98 int n
= sig
->hasthis
+ sig
->param_count
;
102 cinfo
= (CallInfo
*)mono_mempool_alloc0 (mp
, sizeof (CallInfo
) + (sizeof (ArgInfo
) * n
));
104 cinfo
= (CallInfo
*)g_malloc0 (sizeof (CallInfo
) + (sizeof (ArgInfo
) * n
));
107 cinfo
->gsharedvt
= mini_is_gsharedvt_variable_signature (sig
);
110 cinfo
->ret
.storage
= get_storage (mini_get_underlying_type (sig
->ret
), TRUE
);
113 cinfo
->args
[0].storage
= ArgOnStack
;
116 g_assert (sig
->call_convention
!= MONO_CALL_VARARG
);
119 for (i
= 0; i
< sig
->param_count
; ++i
)
120 cinfo
->args
[i
+ sig
->hasthis
].storage
= get_storage (mini_get_underlying_type (sig
->params
[i
]), FALSE
);
126 mono_arch_have_fast_tls (void)
132 mono_arch_get_patch_offset (guint8
*code
)
134 g_error ("mono_arch_get_patch_offset");
138 mono_arch_ip_from_context (void *sigctx
)
140 g_error ("mono_arch_ip_from_context");
144 mono_arch_is_inst_imm (int opcode
, int imm_opcode
, gint64 imm
)
150 mono_arch_lowering_pass (MonoCompile
*cfg
, MonoBasicBlock
*bb
)
155 mono_arch_opcode_supported (int opcode
)
161 mono_arch_output_basic_block (MonoCompile
*cfg
, MonoBasicBlock
*bb
)
163 g_error ("mono_arch_output_basic_block");
167 mono_arch_peephole_pass_1 (MonoCompile
*cfg
, MonoBasicBlock
*bb
)
172 mono_arch_peephole_pass_2 (MonoCompile
*cfg
, MonoBasicBlock
*bb
)
177 mono_arch_regalloc_cost (MonoCompile
*cfg
, MonoMethodVar
*vmv
)
183 mono_arch_get_allocatable_int_vars (MonoCompile
*cfg
)
185 g_error ("mono_arch_get_allocatable_int_vars");
189 mono_arch_get_global_int_regs (MonoCompile
*cfg
)
191 g_error ("mono_arch_get_global_int_regs");
195 mono_arch_allocate_vars (MonoCompile
*cfg
)
197 g_error ("mono_arch_allocate_vars");
201 mono_arch_create_vars (MonoCompile
*cfg
)
203 MonoMethodSignature
*sig
;
207 sig
= mono_method_signature_internal (cfg
->method
);
209 if (!cfg
->arch
.cinfo
)
210 cfg
->arch
.cinfo
= get_call_info (cfg
->mempool
, sig
);
211 cinfo
= (CallInfo
*)cfg
->arch
.cinfo
;
213 // if (cinfo->ret.storage == ArgValuetypeInReg)
214 // cfg->ret_var_is_local = TRUE;
216 sig_ret
= mini_get_underlying_type (sig
->ret
);
217 if (cinfo
->ret
.storage
== ArgValuetypeAddrInIReg
|| cinfo
->ret
.storage
== ArgGsharedVTOnStack
) {
218 cfg
->vret_addr
= mono_compile_create_var (cfg
, mono_get_int_type (), OP_ARG
);
219 if (G_UNLIKELY (cfg
->verbose_level
> 1)) {
220 printf ("vret_addr = ");
221 mono_print_ins (cfg
->vret_addr
);
225 if (cfg
->gen_sdb_seq_points
)
226 g_error ("gen_sdb_seq_points not supported");
228 if (cfg
->method
->save_lmf
)
229 cfg
->create_lmf_var
= TRUE
;
231 if (cfg
->method
->save_lmf
)
236 mono_arch_emit_call (MonoCompile
*cfg
, MonoCallInst
*call
)
238 g_error ("mono_arch_emit_call");
242 mono_arch_emit_epilog (MonoCompile
*cfg
)
244 g_error ("mono_arch_emit_epilog");
248 mono_arch_emit_exceptions (MonoCompile
*cfg
)
250 g_error ("mono_arch_emit_exceptions");
254 mono_arch_emit_inst_for_method (MonoCompile
*cfg
, MonoMethod
*cmethod
, MonoMethodSignature
*fsig
, MonoInst
**args
)
260 mono_arch_emit_outarg_vt (MonoCompile
*cfg
, MonoInst
*ins
, MonoInst
*src
)
262 g_error ("mono_arch_emit_outarg_vt");
266 mono_arch_emit_prolog (MonoCompile
*cfg
)
268 g_error ("mono_arch_emit_prolog");
272 mono_arch_emit_setret (MonoCompile
*cfg
, MonoMethod
*method
, MonoInst
*val
)
274 MonoType
*ret
= mini_get_underlying_type (mono_method_signature_internal (method
)->ret
);
277 if (ret
->type
== MONO_TYPE_R4
) {
278 MONO_EMIT_NEW_UNALU (cfg
, cfg
->r4fp
? OP_RMOVE
: OP_FMOVE
, cfg
->ret
->dreg
, val
->dreg
);
280 } else if (ret
->type
== MONO_TYPE_R8
) {
281 MONO_EMIT_NEW_UNALU (cfg
, OP_FMOVE
, cfg
->ret
->dreg
, val
->dreg
);
283 } else if (ret
->type
== MONO_TYPE_I8
|| ret
->type
== MONO_TYPE_U8
) {
284 MONO_EMIT_NEW_UNALU (cfg
, OP_LMOVE
, cfg
->ret
->dreg
, val
->dreg
);
288 MONO_EMIT_NEW_UNALU (cfg
, OP_MOVE
, cfg
->ret
->dreg
, val
->dreg
);
292 mono_arch_flush_icache (guint8
*code
, gint size
)
297 mono_arch_get_llvm_call_info (MonoCompile
*cfg
, MonoMethodSignature
*sig
)
303 cinfo
= get_call_info (cfg
->mempool
, sig
);
306 linfo
= mono_mempool_alloc0 (cfg
->mempool
, sizeof (LLVMCallInfo
) + (sizeof (LLVMArgInfo
) * n
));
308 if (mini_type_is_vtype (sig
->ret
)) {
309 /* Vtype returned using a hidden argument */
310 linfo
->ret
.storage
= LLVMArgVtypeRetAddr
;
311 // linfo->vret_arg_index = cinfo->vret_arg_index;
313 if (sig
->ret
->type
!= MONO_TYPE_VOID
)
314 linfo
->ret
.storage
= LLVMArgNormal
;
317 for (i
= 0; i
< n
; ++i
) {
318 ArgInfo
*ainfo
= &cinfo
->args
[i
];
320 switch (ainfo
->storage
) {
322 linfo
->args
[i
].storage
= LLVMArgNormal
;
324 case ArgValuetypeAddrOnStack
:
325 linfo
->args
[i
].storage
= LLVMArgVtypeByRef
;
327 case ArgGsharedVTOnStack
:
328 linfo
->args
[i
].storage
= LLVMArgGsharedvtVariable
;
330 case ArgValuetypeAddrInIReg
:
331 g_error ("this is only valid for sig->ret");
340 mono_arch_tailcall_supported (MonoCompile
*cfg
, MonoMethodSignature
*caller_sig
, MonoMethodSignature
*callee_sig
, gboolean virtual_
)
345 #endif // DISABLE_JIT
348 mono_arch_fregname (int reg
)
354 mono_arch_regname (int reg
)
360 mono_arch_get_argument_info (MonoMethodSignature
*csig
, int param_count
, MonoJitArgumentInfo
*arg_info
)
362 g_error ("mono_arch_get_argument_info");
366 mono_arch_get_delegate_invoke_impls (void)
368 g_error ("mono_arch_get_delegate_invoke_impls");
372 mono_arch_get_gsharedvt_call_info (gpointer addr
, MonoMethodSignature
*normal_sig
, MonoMethodSignature
*gsharedvt_sig
, gboolean gsharedvt_in
, gint32 vcall_offset
, gboolean calli
)
374 g_error ("mono_arch_get_gsharedvt_call_info");
379 mono_arch_get_delegate_invoke_impl (MonoMethodSignature
*sig
, gboolean has_target
)
381 g_error ("mono_arch_get_delegate_invoke_impl");
386 #include <emscripten.h>
388 //functions exported to be used by JS
390 EMSCRIPTEN_KEEPALIVE
void mono_set_timeout_exec (int id
);
392 //JS functions imported that we use
393 extern void mono_set_timeout (int t
, int d
);
399 mono_arch_get_this_arg_from_call (host_mgreg_t
*regs
, guint8
*code
)
401 g_error ("mono_arch_get_this_arg_from_call");
405 mono_arch_get_delegate_virtual_invoke_impl (MonoMethodSignature
*sig
, MonoMethod
*method
, int offset
, gboolean load_imt_reg
)
407 g_error ("mono_arch_get_delegate_virtual_invoke_impl");
412 mono_arch_cpu_init (void)
414 // printf ("mono_arch_cpu_init\n");
418 mono_arch_finish_init (void)
420 // printf ("mono_arch_finish_init\n");
424 mono_arch_init (void)
426 // printf ("mono_arch_init\n");
430 mono_arch_cleanup (void)
435 mono_arch_register_lowlevel_calls (void)
440 mono_arch_flush_register_windows (void)
445 mono_arch_find_imt_method (host_mgreg_t
*regs
, guint8
*code
)
447 g_error ("mono_arch_find_static_call_vtable");
448 return (MonoMethod
*) regs
[MONO_ARCH_IMT_REG
];
452 mono_arch_find_static_call_vtable (host_mgreg_t
*regs
, guint8
*code
)
454 g_error ("mono_arch_find_static_call_vtable");
455 return (MonoVTable
*) regs
[MONO_ARCH_RGCTX_REG
];
459 mono_arch_build_imt_trampoline (MonoVTable
*vtable
, MonoDomain
*domain
, MonoIMTCheckItem
**imt_entries
, int count
, gpointer fail_tramp
)
461 g_error ("mono_arch_build_imt_trampoline");
465 mono_arch_cpu_enumerate_simd_versions (void)
471 mono_arch_cpu_optimizations (guint32
*exclude_mask
)
473 /* No arch specific passes yet */
479 mono_arch_context_get_int_reg (MonoContext
*ctx
, int reg
)
481 g_error ("mono_arch_context_get_int_reg");
488 mono_runtime_setup_stat_profiler (void)
490 g_error ("mono_runtime_setup_stat_profiler");
495 mono_runtime_shutdown_stat_profiler (void)
497 g_error ("mono_runtime_shutdown_stat_profiler");
502 MONO_SIG_HANDLER_SIGNATURE (mono_chain_signal
)
504 g_error ("mono_chain_signal");
510 mono_runtime_install_handlers (void)
515 mono_runtime_cleanup_handlers (void)
520 mono_init_native_crash_info (void)
526 mono_cleanup_native_crash_info (void)
532 mono_thread_state_init_from_handle (MonoThreadUnwindState
*tctx
, MonoThreadInfo
*info
, void *sigctx
)
534 g_error ("WASM systems don't support mono_thread_state_init_from_handle");
538 EMSCRIPTEN_KEEPALIVE
void
539 mono_set_timeout_exec (int id
)
542 MonoClass
*klass
= mono_class_load_from_name (mono_defaults
.corlib
, "System.Threading", "WasmRuntime");
545 MonoMethod
*method
= mono_class_get_method_from_name_checked (klass
, "TimeoutCallback", -1, 0, error
);
546 mono_error_assert_ok (error
);
549 gpointer params
[1] = { &id
};
550 MonoObject
*exc
= NULL
;
552 mono_runtime_try_invoke (method
, NULL
, params
, &exc
, error
);
554 //YES we swallow exceptions cuz there's nothing much we can do from here.
555 //FIXME Maybe call the unhandled exception function?
556 if (!is_ok (error
)) {
557 printf ("timeout callback failed due to %s\n", mono_error_get_message (error
));
558 mono_error_cleanup (error
);
562 char *type_name
= mono_type_get_full_name (mono_object_class (exc
));
563 printf ("timeout callback threw a %s\n", type_name
);
571 mono_wasm_set_timeout (int timeout
, int id
)
574 mono_set_timeout (timeout
, id
);
579 mono_arch_register_icall (void)
581 mono_add_internal_call_internal ("System.Threading.WasmRuntime::SetTimeout", mono_wasm_set_timeout
);
585 mono_arch_patch_code_new (MonoCompile
*cfg
, MonoDomain
*domain
, guint8
*code
, MonoJumpInfo
*ji
, gpointer target
)
587 g_error ("mono_arch_patch_code_new");
593 The following functions don't belong here, but are due to laziness.
595 gboolean
mono_w32file_get_file_system_type (const gunichar2
*path
, gunichar2
*fsbuffer
, gint fsbuffersize
);
599 void * getgrnam (const char *name
);
600 void * getgrgid (gid_t gid
);
601 int inotify_init (void);
602 int inotify_rm_watch (int fd
, int wd
);
603 int inotify_add_watch (int fd
, const char *pathname
, uint32_t mask
);
604 int sem_timedwait (sem_t
*sem
, const struct timespec
*abs_timeout
);
610 mono_w32file_get_file_system_type (const gunichar2
*path
, gunichar2
*fsbuffer
, gint fsbuffersize
)
613 gboolean status
= FALSE
;
615 gunichar2
*ret
= g_utf8_to_utf16 ("memfs", -1, NULL
, &len
, NULL
);
616 if (ret
!= NULL
&& len
< fsbuffersize
) {
617 memcpy (fsbuffer
, ret
, len
* sizeof (gunichar2
));
629 //llvm builtin's that we should not have used in the first place
631 #include <sys/types.h>
633 #include <uuid/uuid.h>
635 #ifndef __EMSCRIPTEN_PTHREADS__
636 int pthread_getschedparam (pthread_t thread
, int *policy
, struct sched_param
*param
)
638 g_error ("pthread_getschedparam");
644 pthread_setschedparam(pthread_t thread
, int policy
, const struct sched_param
*param
)
650 pthread_sigmask (int how
, const sigset_t
*set
, sigset_t
*oset
)
657 sigsuspend(const sigset_t
*sigmask
)
659 g_error ("sigsuspend");
666 return 256; //random constant that is the fd limit
670 getgrnam (const char *name
)
684 g_error ("inotify_init");
688 inotify_rm_watch (int fd
, int wd
)
690 g_error ("inotify_rm_watch");
695 inotify_add_watch (int fd
, const char *pathname
, uint32_t mask
)
697 g_error ("inotify_add_watch");
701 #ifndef __EMSCRIPTEN_PTHREADS__
703 sem_timedwait (sem_t
*sem
, const struct timespec
*abs_timeout
)
705 g_error ("sem_timedwait");
710 ssize_t
sendfile(int out_fd
, int in_fd
, off_t
*offset
, size_t count
);
712 ssize_t
sendfile(int out_fd
, int in_fd
, off_t
*offset
, size_t count
)
714 g_error ("sendfile");
719 getpwnam_r (const char *name
, struct passwd
*pwd
, char *buffer
, size_t bufsize
,
720 struct passwd
**result
)
722 g_error ("getpwnam_r");
727 getpwuid_r (uid_t uid
, struct passwd
*pwd
, char *buffer
, size_t bufsize
,
728 struct passwd
**result
)
730 g_error ("getpwuid_r");
739 mono_arch_load_function (MonoJitICallId jit_icall_id
)