private static void CreateDelegateCtor(TypeSpec ts, Target t, TysilaState s) { var ms = ts.m.GetMethodSpec(ts, ".ctor", 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>(0); 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 }); // Store m_target stack_before = ConvertToIR.ldarg(n, c, stack_before, 0); stack_before = ConvertToIR.ldarg(n, c, stack_before, 1); stack_before = ConvertToIR.ldflda(n, c, stack_before, false, out fld_ts, 1, delegate_m_target); stack_before = ConvertToIR.binnumop(n, c, stack_before, cil.Opcode.SingleOpcodes.add, Opcode.ct_intptr, 2); stack_before = ConvertToIR.stind(n, c, stack_before, c.t.GetSize(fld_ts), 1, 0); stack_before.Pop(); // Store method_ptr stack_before = ConvertToIR.ldarg(n, c, stack_before, 0); stack_before = ConvertToIR.ldarg(n, c, stack_before, 2); stack_before = ConvertToIR.ldflda(n, c, stack_before, false, out fld_ts, 1, delegate_method_ptr); stack_before = ConvertToIR.binnumop(n, c, stack_before, cil.Opcode.SingleOpcodes.add, Opcode.ct_intptr, 2); stack_before = ConvertToIR.stind(n, c, stack_before, c.t.GetSize(fld_ts), 1, 0); stack_before.Pop(); // Ret n.irnodes.Add(new cil.CilNode.IRNode { parent = n, opcode = Opcode.oc_ret, 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 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); }