Example #1
0
 private static bool isRefOrContainsRef(TypeSpec ts, Code c)
 {
     var ct = Opcode.GetCTFromType(ts);
     if (ct == Opcode.ct_object)
         return true;
     else if (ct == Opcode.ct_vt)
     {
         System.Collections.Generic.List<TypeSpec> fld_types = new System.Collections.Generic.List<TypeSpec>();
         layout.Layout.GetFieldOffset(ts, null, c.t, out var is_tls, false, fld_types);
         foreach(var fld_type in fld_types)
         {
             if (isRefOrContainsRef(fld_type, c))
                 return true;
         }
         return false;
     }
     else
         return false;
 }
Example #2
0
        private static void CreateDelegateInvoke(TypeSpec ts, Target t, TysilaState s)
        {
            var ms = ts.m.GetMethodSpec(ts, "Invoke", 0, null);

            Code c = new Code {
                t = t, ms = ms, s = s
            };

            t.AllocateLocalVarsArgs(c);
            cil.CilNode n = new cil.CilNode(ms, 0);

            List <cil.CilNode.IRNode> ret = new List <cil.CilNode.IRNode>();

            util.Stack <StackItem> stack_before = new util.Stack <StackItem>();
            TypeSpec fld_ts;

            // Enter
            n.irnodes.Add(new cil.CilNode.IRNode {
                parent = n, opcode = Opcode.oc_enter, stack_before = stack_before, stack_after = stack_before
            });

            // Load m_target
            stack_before = ConvertToIR.ldarg(n, c, stack_before, 0);
            stack_before = ConvertToIR.ldflda(n, c, stack_before, false, out fld_ts, 0, delegate_m_target);
            stack_before = ConvertToIR.binnumop(n, c, stack_before, cil.Opcode.SingleOpcodes.add, Opcode.ct_intptr);
            stack_before = ConvertToIR.ldind(n, c, stack_before, fld_ts);

            // Duplicate and branch to the static implementation if null
            stack_before = ConvertToIR.copy_to_front(n, c, stack_before);
            stack_before = ConvertToIR.ldc(n, c, stack_before, 0, (int)CorElementType.Object);
            var tstatic = c.next_mclabel--;

            stack_before = ConvertToIR.brif(n, c, stack_before, Opcode.cc_eq, tstatic);
            var tstatic_stack_in = new util.Stack <StackItem>(stack_before);

            // Get number of params and push left to right
            var sig_idx = ms.msig;
            var pcount  = ms.m.GetMethodDefSigParamCount(sig_idx);

            for (int i = 0; i < pcount; i++)
            {
                stack_before = ConvertToIR.ldarg(n, c, stack_before, i + 1);
            }

            // Load method_ptr
            stack_before = ConvertToIR.ldarg(n, c, stack_before, 0);
            stack_before = ConvertToIR.ldflda(n, c, stack_before, false, out fld_ts, 0, delegate_method_ptr);
            stack_before = ConvertToIR.binnumop(n, c, stack_before, cil.Opcode.SingleOpcodes.add, Opcode.ct_intptr);
            stack_before = ConvertToIR.ldind(n, c, stack_before, fld_ts);

            // Build new method signature containing System.Object followed by the parameters of Invoke
            sig_idx = ms.m.GetMethodDefSigRetTypeIndex(sig_idx);
            var             ret_ts = ms.m.GetTypeSpec(ref sig_idx, ms.gtparams, ms.gmparams);
            List <TypeSpec> p      = new List <TypeSpec>();

            p.Add(ms.m.SystemObject);
            for (int i = 0; i < pcount; i++)
            {
                p.Add(ms.m.GetTypeSpec(ref sig_idx, ms.gtparams, ms.gmparams));
            }
            var new_msig = c.special_meths.CreateMethodSignature(ret_ts, p.ToArray());

            c.ret_ts = ret_ts;

            // Calli
            stack_before = ConvertToIR.call(n, c, stack_before, true, "noname", c.special_meths, new_msig);

            // Ret
            n.irnodes.Add(new cil.CilNode.IRNode {
                parent = n, opcode = Opcode.oc_ret, ct = ((ret_ts == null) ? ir.Opcode.ct_unknown : Opcode.GetCTFromType(ret_ts)), stack_before = stack_before, stack_after = stack_before
            });

            // Static version of above
            stack_before = mclabel(n, c, tstatic_stack_in, tstatic);
            stack_before = ConvertToIR.pop(n, c, stack_before); // remove null m_target pointer

            // Get number of params and push left to right
            sig_idx = ms.msig;
            pcount  = ms.m.GetMethodDefSigParamCount(sig_idx);
            for (int i = 0; i < pcount; i++)
            {
                stack_before = ConvertToIR.ldarg(n, c, stack_before, i + 1);
            }

            // Load method_ptr
            stack_before = ConvertToIR.ldarg(n, c, stack_before, 0);
            stack_before = ConvertToIR.ldflda(n, c, stack_before, false, out fld_ts, 0, delegate_method_ptr);
            stack_before = ConvertToIR.binnumop(n, c, stack_before, cil.Opcode.SingleOpcodes.add, Opcode.ct_intptr);
            stack_before = ConvertToIR.ldind(n, c, stack_before, fld_ts);

            // Build new method signature containing the parameters of Invoke
            sig_idx = ms.m.GetMethodDefSigRetTypeIndex(sig_idx);
            ret_ts  = ms.m.GetTypeSpec(ref sig_idx, ms.gtparams, ms.gmparams);
            p       = new List <TypeSpec>();
            for (int i = 0; i < pcount; i++)
            {
                p.Add(ms.m.GetTypeSpec(ref sig_idx, ms.gtparams, ms.gmparams));
            }
            new_msig = c.special_meths.CreateMethodSignature(ret_ts, p.ToArray());
            c.ret_ts = ret_ts;

            // Calli
            stack_before = ConvertToIR.call(n, c, stack_before, true, "noname", c.special_meths, new_msig);

            // Ret
            n.irnodes.Add(new cil.CilNode.IRNode {
                parent = n, opcode = Opcode.oc_ret, ct = ((ret_ts == null) ? ir.Opcode.ct_unknown : Opcode.GetCTFromType(ret_ts)), stack_before = stack_before, stack_after = stack_before
            });

            c.cil = new List <cil.CilNode> {
                n
            };
            c.ir = n.irnodes;

            c.starts = new List <cil.CilNode> {
                n
            };

            var msc = new layout.Layout.MethodSpecWithEhdr
            {
                ms = ms,
                c  = c
            };

            s.r.MethodRequestor.Remove(msc);
            s.r.MethodRequestor.Request(msc);
        }
Example #3
0
        private static Stack<StackItem> unsafe_readunaligned_generic(CilNode n, Code c, Stack<StackItem> stack_before)
        {
            var c_ms = c.ms.m.GetMethodSpec(n.inline_uint, c.ms.gtparams, c.ms.gmparams);
            var ts = c_ms.ReturnType;

            var stack_after = new Stack<StackItem>(stack_before);
            stack_after.Pop();
            stack_after.Push(new StackItem { ts = ts });

            n.irnodes.Add(new CilNode.IRNode { parent = n, opcode = Opcode.oc_ldind, ct = Opcode.GetCTFromType(ts), vt_size = c.t.GetSize(ts), imm_ul = 0, imm_l = ts.IsSigned ? 1 : 0, stack_before = stack_before, stack_after = stack_after });

            return stack_after;
        }
Example #4
0
        internal static Code CreateArrayGet(MethodSpec ms,
                                            Target t, TysilaState s)
        {
            Code c = new Code {
                t = t, ms = ms, s = s
            };

            t.AllocateLocalVarsArgs(c);
            cil.CilNode n = new cil.CilNode(ms, 0);

            util.Stack <StackItem> stack_before = new util.Stack <StackItem>(0);

            // Get return type
            var sig_idx = ms.m.GetMethodDefSigRetTypeIndex(ms.msig);
            var ret_ts  = ms.m.GetTypeSpec(ref sig_idx, ms.gtparams, ms.gmparams);

            c.ret_ts = ret_ts;

            if (!ret_ts.Equals(ms.type.other))
            {
                throw new Exception("Array Get return type not the same as element type");
            }

            // Enter
            n.irnodes.Add(new cil.CilNode.IRNode {
                parent = n, opcode = Opcode.oc_enter, stack_before = stack_before, stack_after = stack_before
            });

            // Get offset to the data item
            stack_before = ArrayGetDataItemPtr(n, c, stack_before, ms);

            // Load it
            stack_before = ldind(n, c, stack_before, ret_ts);

            // Ret
            n.irnodes.Add(new cil.CilNode.IRNode {
                parent = n, opcode = Opcode.oc_ret, ct = ((ret_ts == null) ? ir.Opcode.ct_unknown : Opcode.GetCTFromType(ret_ts)), stack_before = stack_before, stack_after = stack_before
            });

            c.cil = new List <cil.CilNode> {
                n
            };
            c.ir = n.irnodes;

            c.starts = new List <cil.CilNode> {
                n
            };

            return(c);
        }