#define SWAP(n) { \
guint ## n *data = (guint ## n *) mono_array_addr (array, char, 0); \
guint ## n *src = (guint ## n *) field_data; \
- int i; \
+ int i, \
+ nEnt = (size / sizeof(guint ## n)); \
\
- for (i = 0; i < (size / sizeof(guint ## n)); i++) { \
+ for (i = 0; i < nEnt; i++) { \
data[i] = read ## n (&src[i]); \
} \
}
ves_icall_Type_GetMethodsByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
{
static MonoClass *MethodInfo_array;
+ MonoError error;
MonoDomain *domain;
MonoArray *res;
MonoVTable *array_vtable;
refklass = mono_class_from_mono_type (reftype->type);
domain = ((MonoObject *)type)->vtable->domain;
array_vtable = mono_class_vtable_full (domain, MethodInfo_array, TRUE);
- if (type->type->byref)
- return mono_array_new_specific (array_vtable, 0);
+ if (type->type->byref) {
+ res = mono_array_new_specific_checked (array_vtable, 0, &error);
+ mono_error_raise_exception (&error);
+
+ return res;
+ }
if (name)
mname = mono_string_to_utf8 (name);
return NULL;
}
- res = mono_array_new_specific (array_vtable, method_array->len);
+ res = mono_array_new_specific_checked (array_vtable, method_array->len, &error);
+ mono_error_raise_exception (&error);
for (i = 0; i < method_array->len; ++i) {
MonoMethod *method = (MonoMethod *)g_ptr_array_index (method_array, i);
#include <mono/io-layer/io-layer.h>
#include "mono/utils/mono-compiler.h"
#include "mono/utils/mono-error.h"
+ #include "mono/utils/mono-error-internals.h"
#include "mono/utils/mono-stack-unwinding.h"
#include "mono/utils/mono-tls.h"
#include "mono/utils/mono-coop-mutex.h"
}; \
tmp_klass; })
/* eclass should be a run-time constant */
- #define mono_array_new_cached(domain, eclass, size) mono_array_new_specific (mono_class_vtable ((domain), mono_array_class_get_cached ((eclass), 1)), (size))
+ #define mono_array_new_cached(domain, eclass, size) ({ \
+ MonoError __error; \
+ MonoVTable *__vtable = mono_class_vtable ((domain), mono_array_class_get_cached ((eclass), 1)); \
+ MonoArray *__arr = mono_array_new_specific_checked (__vtable, (size), &__error); \
+ mono_error_raise_exception (&__error); /* FIXME don't raise here */ \
+ __arr; })
#else
MonoObject *target;
MonoMethod *method;
gpointer delegate_trampoline;
- gpointer rgctx;
+ /* Extra argument passed to the target method in llvmonly mode */
+ gpointer extra_arg;
/*
* If non-NULL, this points to a memory location which stores the address of
* the compiled code of the method, or NULL if it is not yet compiled.
MonoArray*
mono_array_new_full_checked (MonoDomain *domain, MonoClass *array_class, uintptr_t *lengths, intptr_t *lower_bounds, MonoError *error);
+ MonoArray*
+ mono_array_new_specific_checked (MonoVTable *vtable, uintptr_t n, MonoError *error);
+
+ MonoArray*
+ ves_icall_array_new_specific (MonoVTable *vtable, uintptr_t n);
+
#ifndef DISABLE_REMOTING
MonoObject *
mono_remoting_invoke (MonoObject *real_proxy, MonoMethodMessage *msg,
if (managed_alloc)
dest = mono_emit_method_call (cfg, managed_alloc, iargs, NULL);
else
- dest = mono_emit_jit_icall (cfg, mono_array_new_specific, iargs);
+ dest = mono_emit_jit_icall (cfg, ves_icall_array_new_specific, iargs);
dest->dreg = ins->dreg;
}
break;
* at IR level, instead of inlining the icall wrapper. FIXME
*/
if (inlined_wrapper) {
- mono_decompose_long_opts (cfg);
+ if (!COMPILE_LLVM (cfg))
+ mono_decompose_long_opts (cfg);
if (cfg->opt & (MONO_OPT_CONSPROP | MONO_OPT_COPYPROP))
mono_local_cprop (cfg);
}
if (!obj)
return NULL;
- if (cfg->llvm_only) {
- MonoInst *args [16];
-
- /*
- * If the method to be called needs an rgctx, we can't fall back to mono_delegate_ctor (), since it might receive
- * the address of a gshared method. So use a JIT icall.
- * FIXME: Optimize this.
- */
- args [0] = obj;
- args [1] = target;
- args [2] = emit_get_rgctx_method (cfg, context_used, method, MONO_RGCTX_INFO_METHOD);
- mono_emit_jit_icall (cfg, virtual_ ? mono_llvmonly_init_delegate_virtual : mono_llvmonly_init_delegate, args);
-
- return obj;
- }
-
/* Inline the contents of mono_delegate_ctor */
/* Set target field */
MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, obj->dreg, MONO_STRUCT_OFFSET (MonoDelegate, method_code), code_slot_ins->dreg);
}
+ if (cfg->llvm_only) {
+ MonoInst *args [16];
+
+ if (virtual_) {
+ args [0] = obj;
+ args [1] = target;
+ args [2] = emit_get_rgctx_method (cfg, context_used, method, MONO_RGCTX_INFO_METHOD);
+ mono_emit_jit_icall (cfg, mono_llvmonly_init_delegate_virtual, args);
+ } else {
+ args [0] = obj;
+ mono_emit_jit_icall (cfg, mono_llvmonly_init_delegate, args);
+ }
+
+ return obj;
+ }
+
if (cfg->compile_aot) {
MonoDelegateClassMethodPair *del_tramp;
if (managed_alloc)
ins = mono_emit_method_call (cfg, managed_alloc, args, NULL);
else
- ins = mono_emit_jit_icall (cfg, mono_array_new_specific, args);
+ ins = mono_emit_jit_icall (cfg, ves_icall_array_new_specific, args);
} else {
if (cfg->opt & MONO_OPT_SHARED) {
/* Decompose now to avoid problems with references to the domainvar */
#ifndef ENABLE_GSHAREDVT
g_assert_not_reached ();
#endif
+ info->gsharedvt_invoke = TRUE;
if (!callee_gsharedvt) {
/* Invoke a gsharedvt out wrapper instead */
MonoMethod *wrapper = mini_get_gsharedvt_out_sig_wrapper (sig);
MonoMethodSignature *wrapper_sig = mini_get_gsharedvt_out_sig_wrapper_signature (sig->hasthis, sig->ret->type != MONO_TYPE_VOID, sig->param_count);
- info->gsharedvt_invoke = TRUE;
info->wrapper_arg = g_malloc0 (2 * sizeof (gpointer));
- info->wrapper_arg [0] = info->compiled_method;
- info->wrapper_arg [1] = mono_method_needs_static_rgctx_invoke (method, TRUE) ? mini_method_get_rgctx (method) : NULL;
+ info->wrapper_arg [0] = mini_add_method_wrappers_llvmonly (method, info->compiled_method, FALSE, FALSE, &(info->wrapper_arg [1]));
/* Pass has_rgctx == TRUE since the wrapper has an extra arg */
invoke = mono_marshal_get_runtime_invoke_for_sig (wrapper_sig);
/* The out wrapper has the same signature as the compiled gsharedvt method */
MonoMethodSignature *wrapper_sig = mini_get_gsharedvt_out_sig_wrapper_signature (sig->hasthis, sig->ret->type != MONO_TYPE_VOID, sig->param_count);
- info->gsharedvt_invoke = TRUE;
info->wrapper_arg = mono_method_needs_static_rgctx_invoke (method, TRUE) ? mini_method_get_rgctx (method) : NULL;
invoke = mono_marshal_get_runtime_invoke_for_sig (wrapper_sig);
return callee_gsharedvt;
}
-void
-mini_init_delegate (MonoDelegate *del)
+gpointer
+mini_get_delegate_arg (MonoMethod *method, gpointer method_ptr)
{
- if (mono_llvm_only) {
- MonoMethod *method = del->method;
+ gpointer arg = NULL;
- if (mono_method_needs_static_rgctx_invoke (method, FALSE))
- del->rgctx = mini_method_get_rgctx (method);
+ if (mono_method_needs_static_rgctx_invoke (method, FALSE))
+ arg = mini_method_get_rgctx (method);
- /*
- * Avoid adding gsharedvt in wrappers since they might not exist if
- * this delegate is called through a gsharedvt delegate invoke wrapper.
- * Instead, encode that the method is gsharedvt in del->rgctx,
- * the CEE_MONO_CALLI_EXTRA_ARG implementation in the JIT depends on this.
- */
- if (is_callee_gsharedvt_variable (del->method_ptr)) {
- g_assert ((((mgreg_t)del->rgctx) & 1) == 0);
- del->rgctx = (gpointer)(((mgreg_t)del->rgctx) | 1);
- }
+ /*
+ * Avoid adding gsharedvt in wrappers since they might not exist if
+ * this delegate is called through a gsharedvt delegate invoke wrapper.
+ * Instead, encode that the method is gsharedvt in del->extra_arg,
+ * the CEE_MONO_CALLI_EXTRA_ARG implementation in the JIT depends on this.
+ */
+ if (method->is_inflated && is_callee_gsharedvt_variable (method_ptr)) {
+ g_assert ((((mgreg_t)arg) & 1) == 0);
+ arg = (gpointer)(((mgreg_t)arg) | 1);
}
+ return arg;
+}
+
+void
+mini_init_delegate (MonoDelegate *del)
+{
+ if (mono_llvm_only)
+ del->extra_arg = mini_get_delegate_arg (del->method, del->method_ptr);
}
gpointer
register_icall (mono_object_new, "mono_object_new", "object ptr ptr", FALSE);
register_icall (ves_icall_object_new_specific, "ves_icall_object_new_specific", "object ptr", FALSE);
register_icall (mono_array_new, "mono_array_new", "object ptr ptr int32", FALSE);
- register_icall (mono_array_new_specific, "mono_array_new_specific", "object ptr int32", FALSE);
+ register_icall (ves_icall_array_new_specific, "ves_icall_array_new_specific", "object ptr int32", FALSE);
register_icall (mono_runtime_class_init, "mono_runtime_class_init", "void ptr", FALSE);
register_icall (mono_ldftn, "mono_ldftn", "ptr ptr", FALSE);
register_icall (mono_ldvirtfn, "mono_ldvirtfn", "ptr object ptr", FALSE);
register_icall_no_wrapper (mono_llvmonly_get_calling_assembly, "mono_llvmonly_get_calling_assembly", "object");
/* This needs a wrapper so it can have a preserveall cconv */
register_icall (mono_init_vtable_slot, "mono_init_vtable_slot", "ptr ptr int", FALSE);
- register_icall (mono_llvmonly_init_delegate, "mono_llvmonly_init_delegate", "void object object ptr", TRUE);
+ register_icall (mono_llvmonly_init_delegate, "mono_llvmonly_init_delegate", "void object", TRUE);
register_icall (mono_llvmonly_init_delegate_virtual, "mono_llvmonly_init_delegate_virtual", "void object object ptr", TRUE);
register_icall (mono_get_assembly_object, "mono_get_assembly_object", "object ptr", TRUE);
register_icall (mono_get_method_object, "mono_get_method_object", "object ptr", TRUE);