Merge pull request #4621 from alexanderkyte/strdup_env
[mono.git] / mono / mini / method-to-ir.c
index 6e30cdc295716ad1ca163fbaac78269ba4a07bd4..62bc0f5fc52ad32eaa28fe5b38d88c038492544f 100644 (file)
@@ -1,5 +1,6 @@
-/*
- * method-to-ir.c: Convert CIL to the JIT internal representation
+/**
+ * \file
+ * Convert CIL to the JIT internal representation
  *
  * Author:
  *   Paolo Molaro (lupus@ximian.com)
@@ -1260,16 +1261,22 @@ mono_get_got_var (MonoCompile *cfg)
        return cfg->got_var;
 }
 
-static MonoInst *
-mono_get_vtable_var (MonoCompile *cfg)
+static void
+mono_create_rgctx_var (MonoCompile *cfg)
 {
-       g_assert (cfg->gshared);
-
        if (!cfg->rgctx_var) {
                cfg->rgctx_var = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL);
                /* force the var to be stack allocated */
                cfg->rgctx_var->flags |= MONO_INST_VOLATILE;
        }
+}
+
+static MonoInst *
+mono_get_vtable_var (MonoCompile *cfg)
+{
+       g_assert (cfg->gshared);
+
+       mono_create_rgctx_var (cfg);
 
        return cfg->rgctx_var;
 }
@@ -1825,47 +1832,35 @@ emit_push_lmf (MonoCompile *cfg)
        if (!cfg->lmf_ir)
                return;
 
-       if (cfg->lmf_ir_mono_lmf) {
-               MonoInst *lmf_vara_ins, *lmf_ins;
-               /* Load current lmf */
-               lmf_ins = mono_create_tls_get (cfg, TLS_KEY_LMF);
-               g_assert (lmf_ins);
-               EMIT_NEW_VARLOADA (cfg, lmf_vara_ins, cfg->lmf_var, NULL);
-               /* Save previous_lmf */
-               EMIT_NEW_STORE_MEMBASE (cfg, ins, OP_STORE_MEMBASE_REG, lmf_vara_ins->dreg, MONO_STRUCT_OFFSET (MonoLMF, previous_lmf), lmf_ins->dreg);
-               /* Set new LMF */
-               mono_create_tls_set (cfg, lmf_vara_ins, TLS_KEY_LMF);
-       } else {
-               int lmf_reg, prev_lmf_reg;
-               /*
-                * Store lmf_addr in a variable, so it can be allocated to a global register.
-                */
-               if (!cfg->lmf_addr_var)
-                       cfg->lmf_addr_var = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL);
+       int lmf_reg, prev_lmf_reg;
+       /*
+        * Store lmf_addr in a variable, so it can be allocated to a global register.
+        */
+       if (!cfg->lmf_addr_var)
+               cfg->lmf_addr_var = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL);
 
 #ifdef HOST_WIN32
-               ins = mono_create_tls_get (cfg, TLS_KEY_JIT_TLS);
-               g_assert (ins);
-               int jit_tls_dreg = ins->dreg;
+       ins = mono_create_tls_get (cfg, TLS_KEY_JIT_TLS);
+       g_assert (ins);
+       int jit_tls_dreg = ins->dreg;
 
-               lmf_reg = alloc_preg (cfg);
-               EMIT_NEW_BIALU_IMM (cfg, lmf_ins, OP_PADD_IMM, lmf_reg, jit_tls_dreg, MONO_STRUCT_OFFSET (MonoJitTlsData, lmf));
+       lmf_reg = alloc_preg (cfg);
+       EMIT_NEW_BIALU_IMM (cfg, lmf_ins, OP_PADD_IMM, lmf_reg, jit_tls_dreg, MONO_STRUCT_OFFSET (MonoJitTlsData, lmf));
 #else
-               lmf_ins = mono_create_tls_get (cfg, TLS_KEY_LMF_ADDR);
-               g_assert (lmf_ins);
+       lmf_ins = mono_create_tls_get (cfg, TLS_KEY_LMF_ADDR);
+       g_assert (lmf_ins);
 #endif
-               lmf_ins->dreg = cfg->lmf_addr_var->dreg;
+       lmf_ins->dreg = cfg->lmf_addr_var->dreg;
 
-               EMIT_NEW_VARLOADA (cfg, ins, cfg->lmf_var, NULL);
-               lmf_reg = ins->dreg;
+       EMIT_NEW_VARLOADA (cfg, ins, cfg->lmf_var, NULL);
+       lmf_reg = ins->dreg;
 
-               prev_lmf_reg = alloc_preg (cfg);
-               /* Save previous_lmf */
-               EMIT_NEW_LOAD_MEMBASE (cfg, ins, OP_LOAD_MEMBASE, prev_lmf_reg, cfg->lmf_addr_var->dreg, 0);
-               EMIT_NEW_STORE_MEMBASE (cfg, ins, OP_STORE_MEMBASE_REG, lmf_reg, MONO_STRUCT_OFFSET (MonoLMF, previous_lmf), prev_lmf_reg);
-               /* Set new lmf */
-               EMIT_NEW_STORE_MEMBASE (cfg, ins, OP_STORE_MEMBASE_REG, cfg->lmf_addr_var->dreg, 0, lmf_reg);
-       }
+       prev_lmf_reg = alloc_preg (cfg);
+       /* Save previous_lmf */
+       EMIT_NEW_LOAD_MEMBASE (cfg, ins, OP_LOAD_MEMBASE, prev_lmf_reg, cfg->lmf_addr_var->dreg, 0);
+       EMIT_NEW_STORE_MEMBASE (cfg, ins, OP_STORE_MEMBASE_REG, lmf_reg, MONO_STRUCT_OFFSET (MonoLMF, previous_lmf), prev_lmf_reg);
+       /* Set new lmf */
+       EMIT_NEW_STORE_MEMBASE (cfg, ins, OP_STORE_MEMBASE_REG, cfg->lmf_addr_var->dreg, 0, lmf_reg);
 }
 
 /*
@@ -1885,26 +1880,19 @@ emit_pop_lmf (MonoCompile *cfg)
        EMIT_NEW_VARLOADA (cfg, ins, cfg->lmf_var, NULL);
        lmf_reg = ins->dreg;
 
-       if (cfg->lmf_ir_mono_lmf) {
-               /* Load previous_lmf */
-               EMIT_NEW_LOAD_MEMBASE (cfg, ins, OP_LOAD_MEMBASE, alloc_preg (cfg), lmf_reg, MONO_STRUCT_OFFSET (MonoLMF, previous_lmf));
-               /* Set new LMF */
-               mono_create_tls_set (cfg, ins, TLS_KEY_LMF);
-       } else {
-               int prev_lmf_reg;
-               /*
-                * Emit IR to pop the LMF:
-                * *(lmf->lmf_addr) = lmf->prev_lmf
-                */
-               /* This could be called before emit_push_lmf () */
-               if (!cfg->lmf_addr_var)
-                       cfg->lmf_addr_var = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL);
-               lmf_addr_reg = cfg->lmf_addr_var->dreg;
+       int prev_lmf_reg;
+       /*
+        * Emit IR to pop the LMF:
+        * *(lmf->lmf_addr) = lmf->prev_lmf
+        */
+       /* This could be called before emit_push_lmf () */
+       if (!cfg->lmf_addr_var)
+               cfg->lmf_addr_var = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL);
+       lmf_addr_reg = cfg->lmf_addr_var->dreg;
 
-               prev_lmf_reg = alloc_preg (cfg);
-               EMIT_NEW_LOAD_MEMBASE (cfg, ins, OP_LOAD_MEMBASE, prev_lmf_reg, lmf_reg, MONO_STRUCT_OFFSET (MonoLMF, previous_lmf));
-               EMIT_NEW_STORE_MEMBASE (cfg, ins, OP_STORE_MEMBASE_REG, lmf_addr_reg, 0, prev_lmf_reg);
-       }
+       prev_lmf_reg = alloc_preg (cfg);
+       EMIT_NEW_LOAD_MEMBASE (cfg, ins, OP_LOAD_MEMBASE, prev_lmf_reg, lmf_reg, MONO_STRUCT_OFFSET (MonoLMF, previous_lmf));
+       EMIT_NEW_STORE_MEMBASE (cfg, ins, OP_STORE_MEMBASE_REG, lmf_addr_reg, 0, prev_lmf_reg);
 }
 
 static void
@@ -2857,6 +2845,8 @@ emit_llvmonly_calli (MonoCompile *cfg, MonoMethodSignature *fsig, MonoInst **arg
 static gboolean
 direct_icalls_enabled (MonoCompile *cfg)
 {
+       return FALSE;
+
        /* LLVM on amd64 can't handle calls to non-32 bit addresses */
 #ifdef TARGET_AMD64
        if (cfg->compile_llvm && !cfg->llvm_only)
@@ -4899,18 +4889,18 @@ static MonoBreakPolicyFunc break_policy_func = always_insert_breakpoint;
 
 /**
  * mono_set_break_policy:
- * policy_callback: the new callback function
+ * \param policy_callback the new callback function
  *
  * Allow embedders to decide wherther to actually obey breakpoint instructions
- * (both break IL instructions and Debugger.Break () method calls), for example
+ * (both break IL instructions and \c Debugger.Break method calls), for example
  * to not allow an app to be aborted by a perfectly valid IL opcode when executing
  * untrusted or semi-trusted code.
  *
- * @policy_callback will be called every time a break point instruction needs to
- * be inserted with the method argument being the method that calls Debugger.Break()
- * or has the IL break instruction. The callback should return #MONO_BREAK_POLICY_NEVER
+ * \p policy_callback will be called every time a break point instruction needs to
+ * be inserted with the method argument being the method that calls \c Debugger.Break
+ * or has the IL \c break instruction. The callback should return \c MONO_BREAK_POLICY_NEVER
  * if it wants the breakpoint to not be effective in the given method.
- * #MONO_BREAK_POLICY_ALWAYS is the default.
+ * \c MONO_BREAK_POLICY_ALWAYS is the default.
  */
 void
 mono_set_break_policy (MonoBreakPolicyFunc policy_callback)
@@ -6908,14 +6898,12 @@ initialize_array_data (MonoMethod *method, gboolean aot, unsigned char *ip, Mono
                        return NULL;
                if (strcmp (cmethod->name, "InitializeArray") || strcmp (cmethod->klass->name, "RuntimeHelpers") || cmethod->klass->image != mono_defaults.corlib)
                        return NULL;
-               switch (mono_type_get_underlying_type (&klass->byval_arg)->type) {
-               case MONO_TYPE_BOOLEAN:
+               switch (mini_get_underlying_type (&klass->byval_arg)->type) {
                case MONO_TYPE_I1:
                case MONO_TYPE_U1:
                        size = 1; break;
                /* we need to swap on big endian, so punt. Should we handle R4 and R8 as well? */
 #if TARGET_BYTE_ORDER == G_LITTLE_ENDIAN
-               case MONO_TYPE_CHAR:
                case MONO_TYPE_I2:
                case MONO_TYPE_U2:
                        size = 2; break;
@@ -12360,6 +12348,21 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                ins->type = STACK_I4;
                                MONO_ADD_INS (cfg->cbb, ins);
 
+                               ip += 2;
+                               *sp++ = ins;
+                               break;
+                       case CEE_MONO_GET_RGCTX_ARG:
+                               CHECK_OPSIZE (2);
+                               CHECK_STACK_OVF (1);
+
+                               mono_create_rgctx_var (cfg);
+
+                               MONO_INST_NEW (cfg, ins, OP_MOVE);
+                               ins->dreg = alloc_dreg (cfg, STACK_PTR);
+                               ins->sreg1 = cfg->rgctx_var->dreg;
+                               ins->type = STACK_PTR;
+                               MONO_ADD_INS (cfg->cbb, ins);
+
                                ip += 2;
                                *sp++ = ins;
                                break;