#include "mono/utils/mono-memory-model.h"
#include "mono/utils/atomic.h"
#include <mono/utils/mono-threads.h>
+#include <mono/utils/mono-threads-coop.h>
#include <mono/utils/mono-error-internals.h>
#include <string.h>
MonoClass *klass;
int i, argnum, *tmp_locals;
int type, param_shift = 0;
- static MonoMethodSignature *get_last_error_sig = NULL;
int coop_gc_stack_dummy, coop_gc_var;
memset (&m, 0, sizeof (m));
}
}
- if (MONO_TYPE_ISSTRUCT (sig->ret)) {
- MonoClass *klass = mono_class_from_mono_type (sig->ret);
- mono_class_init (klass);
- if (!(((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) || klass->blittable)) {
- /* This is used by emit_marshal_vtype (), but it needs to go right before the call */
- mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
- mono_mb_emit_byte (mb, CEE_MONO_VTADDR);
- mono_mb_emit_stloc (mb, m.vtaddr_var);
- }
- }
-
- /* Unblock before converting the result, since that can involve calls into the runtime */
- if (mono_threads_is_coop_enabled ()) {
- mono_mb_emit_ldloc (mb, coop_gc_var);
- mono_mb_emit_ldloc_addr (mb, coop_gc_stack_dummy);
- mono_mb_emit_icall (mb, mono_threads_exit_gc_safe_region_unbalanced);
- }
-
/* Set LastError if needed */
if (piinfo->piflags & PINVOKE_ATTRIBUTE_SUPPORTS_LAST_ERROR) {
+#ifdef TARGET_WIN32
+ static MonoMethodSignature *get_last_error_sig = NULL;
if (!get_last_error_sig) {
get_last_error_sig = mono_metadata_signature_alloc (mono_defaults.corlib, 0);
get_last_error_sig->ret = &mono_defaults.int_class->byval_arg;
get_last_error_sig->pinvoke = 1;
}
-#ifdef TARGET_WIN32
/*
* Have to call GetLastError () early and without a wrapper, since various runtime components could
* clobber its value.
#endif
}
+ if (MONO_TYPE_ISSTRUCT (sig->ret)) {
+ MonoClass *klass = mono_class_from_mono_type (sig->ret);
+ mono_class_init (klass);
+ if (!(((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) || klass->blittable)) {
+ /* This is used by emit_marshal_vtype (), but it needs to go right before the call */
+ mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
+ mono_mb_emit_byte (mb, CEE_MONO_VTADDR);
+ mono_mb_emit_stloc (mb, m.vtaddr_var);
+ }
+ }
+
+ /* Unblock before converting the result, since that can involve calls into the runtime */
+ if (mono_threads_is_coop_enabled ()) {
+ mono_mb_emit_ldloc (mb, coop_gc_var);
+ mono_mb_emit_ldloc_addr (mb, coop_gc_stack_dummy);
+ mono_mb_emit_icall (mb, mono_threads_exit_gc_safe_region_unbalanced);
+ }
+
/* convert the result */
if (!sig->ret->byref) {
MonoMarshalSpec *spec = mspecs [0];