Merge pull request #3142 from henricm/fix-for-win-mono_string_to_utf8
[mono.git] / mono / mini / method-to-ir.c
index 4017d42b6df005c735e688aea0d9193dff4dcb1e..b0ca01954dd0902a91f25a02e4eda756f68fef2d 100644 (file)
@@ -64,6 +64,7 @@
 #include <mono/utils/mono-error-internals.h>
 #include <mono/metadata/mono-basic-block.h>
 #include <mono/metadata/reflection-internals.h>
+#include <mono/utils/mono-threads-coop.h>
 
 #include "trace.h"
 
                if (cfg->exception_type != MONO_EXCEPTION_NONE) \
                        goto exception_exit;                                            \
        } while (0)
-#define METHOD_ACCESS_FAILURE(method, cmethod) do {                    \
-               method_access_failure ((cfg), (method), (cmethod));                     \
-               goto exception_exit;                                                                            \
-       } while (0)
 #define FIELD_ACCESS_FAILURE(method, field) do {                                       \
                field_access_failure ((cfg), (method), (field));                        \
                goto exception_exit;    \
@@ -377,17 +374,6 @@ break_on_unverified (void)
                G_BREAKPOINT ();
 }
 
-static MONO_NEVER_INLINE void
-method_access_failure (MonoCompile *cfg, MonoMethod *method, MonoMethod *cil_method)
-{
-       char *method_fname = mono_method_full_name (method, TRUE);
-       char *cil_method_fname = mono_method_full_name (cil_method, TRUE);
-       mono_cfg_set_exception (cfg, MONO_EXCEPTION_MONO_ERROR);
-       mono_error_set_generic_error (&cfg->error, "System", "MethodAccessException", "Method `%s' is inaccessible from method `%s'\n", cil_method_fname, method_fname);
-       g_free (method_fname);
-       g_free (cil_method_fname);
-}
-
 static MONO_NEVER_INLINE void
 field_access_failure (MonoCompile *cfg, MonoMethod *method, MonoClassField *field)
 {
@@ -3156,6 +3142,18 @@ mono_emit_widen_call_res (MonoCompile *cfg, MonoInst *ins, MonoMethodSignature *
        return ins;
 }
 
+
+static void
+emit_method_access_failure (MonoCompile *cfg, MonoMethod *method, MonoMethod *cil_method)
+{
+       MonoInst *args [16];
+
+       args [0] = emit_get_rgctx_method (cfg, mono_method_check_context_used (method), method, MONO_RGCTX_INFO_METHOD);
+       args [1] = emit_get_rgctx_method (cfg, mono_method_check_context_used (cil_method), cil_method, MONO_RGCTX_INFO_METHOD);
+
+       mono_emit_jit_icall (cfg, mono_throw_method_access, args);
+}
+
 static MonoMethod*
 get_memcpy_method (void)
 {
@@ -4527,6 +4525,9 @@ handle_castclass (MonoCompile *cfg, MonoClass *klass, MonoInst *src, guint8 *ip,
        int context_used;
        MonoInst *klass_inst = NULL, *res;
 
+       if (src->opcode == OP_PCONST && src->inst_p0 == 0)
+               return src;
+
        context_used = mini_class_check_context_used (cfg, klass);
 
        if (!context_used && mini_class_has_reference_variant_generic_argument (cfg, klass, context_used)) {
@@ -4558,7 +4559,7 @@ handle_castclass (MonoCompile *cfg, MonoClass *klass, MonoInst *src, guint8 *ip,
        if (context_used) {
                MonoInst *args [3];
 
-               if(mini_class_has_reference_variant_generic_argument (cfg, klass, context_used) || is_complex_isinst (klass)) {
+               if (mini_class_has_reference_variant_generic_argument (cfg, klass, context_used) || is_complex_isinst (klass)) {
                        MonoInst *cache_ins;
 
                        cache_ins = emit_get_rgctx_klass (cfg, context_used, klass, MONO_RGCTX_INFO_CAST_CACHE);
@@ -6806,7 +6807,7 @@ mini_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign
                    cfg->compile_aot && !cfg->llvm_only) {
                        MonoInst *pi;
                        MonoJumpInfoToken *ji;
-                       MonoString *s;
+                       char *s;
 
                        // FIXME: llvmonly
 
@@ -6825,13 +6826,13 @@ mini_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign
 
                        NULLIFY_INS (args [0]);
 
-                       // FIXME: Ugly
-                       s = mono_ldstr_checked (cfg->domain, ji->image, mono_metadata_token_index (ji->token), &cfg->error);
+                       s = mono_ldstr_utf8 (ji->image, mono_metadata_token_index (ji->token), &cfg->error);
                        return_val_if_nok (&cfg->error, NULL);
+
                        MONO_INST_NEW (cfg, ins, OP_OBJC_GET_SELECTOR);
                        ins->dreg = mono_alloc_ireg (cfg);
                        // FIXME: Leaks
-                       ins->inst_p0 = mono_string_to_utf8 (s);
+                       ins->inst_p0 = s;
                        MONO_ADD_INS (cfg->cbb, ins);
                        return ins;
                }
@@ -9265,7 +9266,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                }
                                if (!mono_method_can_access_method (method_definition, target_method) &&
                                        !mono_method_can_access_method (method, cil_method))
-                                       METHOD_ACCESS_FAILURE (method, cil_method);
+                                       emit_method_access_failure (cfg, method, cil_method);
                        }
 
                        if (mono_security_core_clr_enabled ())
@@ -12767,6 +12768,22 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                ip += 6;
                                break;
                        }
+                       case CEE_MONO_ATOMIC_STORE_I4: {
+                               g_assert (mono_arch_opcode_supported (OP_ATOMIC_STORE_I4));
+
+                               CHECK_OPSIZE (6);
+                               CHECK_STACK (2);
+                               sp -= 2;
+
+                               MONO_INST_NEW (cfg, ins, OP_ATOMIC_STORE_I4);
+                               ins->dreg = sp [0]->dreg;
+                               ins->sreg1 = sp [1]->dreg;
+                               ins->backend.memory_barrier_kind = (int) read32 (ip + 2);
+                               MONO_ADD_INS (cfg->cbb, ins);
+
+                               ip += 6;
+                               break;
+                       }
                        case CEE_MONO_JIT_ATTACH: {
                                MonoInst *args [16], *domain_ins;
                                MonoInst *ad_ins, *jit_tls_ins;
@@ -13076,7 +13093,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
 
                                cil_method = cmethod;
                                if (!dont_verify && !cfg->skip_visibility && !mono_method_can_access_method (method, cmethod))
-                                       METHOD_ACCESS_FAILURE (method, cil_method);
+                                       emit_method_access_failure (cfg, method, cil_method);
 
                                if (mono_security_core_clr_enabled ())
                                        ensure_method_is_allowed_to_call_method (cfg, method, cmethod);