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; }
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); }
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; }
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); }