Exemple #1
0
 internal DelegateInvokeObjectArrayThunk(DelegateInfo delegateInfo)
     : base(delegateInfo)
 {
 }
Exemple #2
0
 internal DelegateInvokeClosedStaticThunk(DelegateInfo delegateInfo)
     : base(delegateInfo)
 {
 }
Exemple #3
0
 internal DelegateInvokeInstanceClosedOverGenericMethodThunk(DelegateInfo delegateInfo)
     : base(delegateInfo)
 {
 }
Exemple #4
0
        bool checkProxyMethod(MethodDefinition method, out DelegateInfo info)
        {
            info = null;
            if (!method.IsStatic || method.Body == null)
                return false;

            var instrs = method.Body.Instructions;
            if (instrs.Count < 7)
                return false;

            int index = 0;

            if (instrs[index].OpCode.Code != Code.Ldsfld)
                return false;
            var field = instrs[index++].Operand as FieldDefinition;
            if (field == null || !field.IsStatic)
                return false;
            if (!MemberReferenceHelper.compareTypes(method.DeclaringType, field.DeclaringType))
                return false;

            if (!DotNetUtils.isBrtrue(instrs[index++]))
                return false;
            if (instrs[index++].OpCode.Code != Code.Ldnull)
                return false;
            if (instrs[index].OpCode.Code != Code.Ldftn)
                return false;
            var calledMethod = instrs[index++].Operand as MethodReference;
            if (calledMethod == null)
                return false;
            if (instrs[index++].OpCode.Code != Code.Newobj)
                return false;
            if (instrs[index].OpCode.Code != Code.Stsfld)
                return false;
            if (!MemberReferenceHelper.compareFieldReference(field, instrs[index++].Operand as FieldReference))
                return false;
            if (instrs[index].OpCode.Code != Code.Ldsfld)
                return false;
            if (!MemberReferenceHelper.compareFieldReference(field, instrs[index++].Operand as FieldReference))
                return false;

            for (int i = 0; i < method.Parameters.Count; i++) {
                if (index >= instrs.Count)
                    return false;
                if (DotNetUtils.getArgIndex(instrs[index++]) != i)
                    return false;
            }

            if (index + 2 > instrs.Count)
                return false;
            var call = instrs[index++];
            if (call.OpCode.Code != Code.Callvirt)
                return false;

            if (instrs[index++].OpCode.Code != Code.Ret)
                return false;

            info = new DelegateInfo(field, calledMethod, OpCodes.Call);
            return true;
        }
Exemple #5
0
 internal DelegateInvokeOpenInstanceThunk(DelegateInfo delegateInfo)
     : base(delegateInfo)
 {
 }
Exemple #6
0
 internal DelegateInvokeOpenStaticThunk(DelegateInfo delegateInfo)
     : base(delegateInfo)
 {
 }
Exemple #7
0
 internal DelegateGetThunkMethodOverride(DelegateInfo delegateInfo)
 {
     _delegateInfo = delegateInfo;
 }
Exemple #8
0
 internal DelegateInvokeInstanceClosedOverGenericMethodThunk(DelegateInfo delegateInfo)
     : base(delegateInfo)
 {
 }
Exemple #9
0
 public MyInfo(MethodDef method, DelegateInfo delegateInfo)
 {
     this.method       = method;
     this.delegateInfo = delegateInfo;
 }
Exemple #10
0
        bool checkProxyMethod(MethodDefinition method, out DelegateInfo info)
        {
            info = null;
            if (!method.IsStatic || method.Body == null)
            {
                return(false);
            }

            var instrs = method.Body.Instructions;

            if (instrs.Count < 7)
            {
                return(false);
            }

            int index = 0;

            if (instrs[index].OpCode.Code != Code.Ldsfld)
            {
                return(false);
            }
            var field = instrs[index++].Operand as FieldDefinition;

            if (field == null || !field.IsStatic)
            {
                return(false);
            }
            if (!MemberReferenceHelper.compareTypes(method.DeclaringType, field.DeclaringType))
            {
                return(false);
            }

            if (!DotNetUtils.isBrtrue(instrs[index++]))
            {
                return(false);
            }
            if (instrs[index++].OpCode.Code != Code.Ldnull)
            {
                return(false);
            }
            if (instrs[index].OpCode.Code != Code.Ldftn)
            {
                return(false);
            }
            var calledMethod = instrs[index++].Operand as MethodReference;

            if (calledMethod == null)
            {
                return(false);
            }
            if (instrs[index++].OpCode.Code != Code.Newobj)
            {
                return(false);
            }
            if (instrs[index].OpCode.Code != Code.Stsfld)
            {
                return(false);
            }
            if (!MemberReferenceHelper.compareFieldReference(field, instrs[index++].Operand as FieldReference))
            {
                return(false);
            }
            if (instrs[index].OpCode.Code != Code.Ldsfld)
            {
                return(false);
            }
            if (!MemberReferenceHelper.compareFieldReference(field, instrs[index++].Operand as FieldReference))
            {
                return(false);
            }

            for (int i = 0; i < method.Parameters.Count; i++)
            {
                if (index >= instrs.Count)
                {
                    return(false);
                }
                if (DotNetUtils.getArgIndex(instrs[index++]) != i)
                {
                    return(false);
                }
            }

            if (index + 2 > instrs.Count)
            {
                return(false);
            }
            var call = instrs[index++];

            if (call.OpCode.Code != Code.Callvirt)
            {
                return(false);
            }

            if (instrs[index++].OpCode.Code != Code.Ret)
            {
                return(false);
            }

            info = new DelegateInfo(field, calledMethod, OpCodes.Call);
            return(true);
        }
        protected void Page_Load(object sender, EventArgs e)
        {
            string                action  = Request["action"];
            string                sql     = "";
            DataTable             dt      = null;
            ChouJin               cjEnt   = null;
            ShouKuan              skEnt   = null;
            ChouJinDetail         cjdEnt  = null;
            ChouJinResult         cjrEnt  = null;
            string                id      = Request["id"];
            IList <ShouKuan>      skEnts  = null;
            IList <ChouJinDetail> cjdEnts = null;
            IList <ChouJinResult> cjrEnts = null;

            switch (action)
            {
            case "loadyear":
                sql = "select value as year from NCRL_Portal..SysEnumeration where ParentId='058fbee9-0a9a-4b25-b343-ea8c05396632' order by SortIndex asc";
                dt  = DataHelper.QueryDataTable(sql);
                Response.Write("{rows:" + JsonHelper.GetJsonStringFromDataTable(dt) + "}");
                Response.End();
                break;

            case "loadmonth":
                sql = "select value as month from NCRL_Portal..SysEnumeration where ParentId='b25e537b-34e3-4437-87af-692e00facd73' order by SortIndex asc";
                dt  = DataHelper.QueryDataTable(sql);
                Response.Write("{rows:" + JsonHelper.GetJsonStringFromDataTable(dt) + "}");
                Response.End();
                break;

            case "create":
                cjEnt = JsonHelper.GetObject <ChouJin>(Request["formdata"]);
                cjEnt.DoCreate();
                Response.Write("{success:true,id:'" + cjEnt.Id + "'}");
                Response.End();
                break;

            case "update":
                cjEnt = JsonHelper.GetObject <ChouJin>(Request["formdata"]);
                ChouJin        originalEnt = ChouJin.Find(cjEnt.Id);
                EasyDictionary dic         = JsonHelper.GetObject <EasyDictionary>(Request["formdata"]);
                originalEnt = DataHelper.MergeData <ChouJin>(originalEnt, cjEnt, dic.Keys);
                originalEnt.DoUpdate();
                Response.Write("{success:true,id:'" + cjEnt.Id + "'}");
                Response.End();
                break;

            case "loadform":
                cjEnt = ChouJin.Find(id);
                Response.Write("{success:true,data:" + JsonHelper.GetJsonString(cjEnt) + "}");
                Response.End();
                break;

            case "loadshoukuan":
                skEnts = ShouKuan.FindAllByProperty(ShouKuan.Prop_ShouKuanDate, ShouKuan.Prop_ChouJinId, id);
                if (skEnts.Count == 0)
                {
                    cjEnt = ChouJin.Find(id);
                    sql   = @"select a.Id,a.ProjectId,a.InvoiceId,a.ShouKuanAmount,a.ShouKuanDate,a.ShiJiShouFei,
                        a.YiFenPercent,a.ChouJinAmount,b.ProjectName,c.InvoiceNo
                        from NCRL_SP..ShouKuan a left join NCRL_SP..Project b on a.ProjectId=b.Id
                        left join NCRL_SP..Invoice c on a.InvoiceId=c.Id
                        where YiFenPercent is null and  year(ShouKuanDate)='" + cjEnt.BelongYear + "' and month(ShouKuanDate)='" + (Convert.ToInt32(cjEnt.BelongMonth) - 1) + "' and isnull(a.Status,'')<>'已作废' order by ShouKuanDate asc";
                }
                else
                {
                    sql = @"select a.Id,a.ProjectId,a.InvoiceId,a.ShouKuanAmount,a.ShouKuanDate,a.ShiJiShouFei,
                        a.YiFenPercent,a.ChouJinAmount,b.ProjectName,c.InvoiceNo
                        from NCRL_SP..ShouKuan a left join NCRL_SP..Project b on a.ProjectId=b.Id
                        left join NCRL_SP..Invoice c on a.InvoiceId=c.Id
                        where ChouJinId='" + id + "'  order by a.ShouKuanDate asc";
                }
                dt = DataHelper.QueryDataTable(sql);
                Response.Write("{rows:" + JsonHelper.GetJsonStringFromDataTable(dt) + "}");
                Response.End();
                break;

            case "updateshoukuan":
                string   shoukuanids = Request["shoukuanids"];
                string[] idarray     = shoukuanids.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                foreach (string str in idarray)
                {
                    skEnt           = ShouKuan.Find(str);
                    skEnt.ChouJinId = id;
                    skEnt.DoUpdate();
                }
                //顺便把酬金分配明细的store构建后送到前端  为动态页面的生成提供数据基础
                skEnts = ShouKuan.FindAllByProperty(ShouKuan.Prop_ShouKuanDate, ShouKuan.Prop_ChouJinId, id);
                DataTable dt2 = new DataTable();
                //构建表格列
                // dc = new DataColumn("MajorName");
                //dt2.Columns.Add(dc);
                DataColumn dc = new DataColumn("UserId");
                dt2.Columns.Add(dc);
                dc = new DataColumn("UserName");
                dt2.Columns.Add(dc);
                dc = new DataColumn("StageAmount");
                dt2.Columns.Add(dc);
                foreach (ShouKuan tempEnt in skEnts)
                {
                    dc = new DataColumn(tempEnt.Id + "@A");
                    dt2.Columns.Add(dc);
                    dc = new DataColumn(tempEnt.Id + "@B");
                    dt2.Columns.Add(dc);
                    dc = new DataColumn(tempEnt.Id + "@C");
                    dt2.Columns.Add(dc);
                }       //构建表格行  先构建前面的特殊5行
                DataRow dr1  = dt2.NewRow();
                DataRow dr2  = dt2.NewRow();
                DataRow dr3  = dt2.NewRow();
                DataRow dr4  = dt2.NewRow();
                DataRow dr5  = dt2.NewRow();
                Project pEnt = null;
                dr1["UserName"] = "******"; dr2["UserName"] = "******"; dr3["UserName"] = "******"; dr4["UserName"] = "******"; dr5["UserName"] = "******";
                foreach (ShouKuan tempEnt in skEnts)
                {
                    pEnt = Project.Find(tempEnt.ProjectId);
                    dr1[tempEnt.Id + "@A"] = pEnt.ProjectName;
                    dr1[tempEnt.Id + "@C"] = tempEnt.ShouKuanAmount;    //获取收款金额
                    if (!string.IsNullOrEmpty(pEnt.DelegateInfoId))
                    {
                        dr2[tempEnt.Id + "@A"] = DelegateInfo.Find(pEnt.DelegateInfoId).DelegateName;    //第二行收款记录第一列显示窗口名称 第三列显示窗口比例
                    }
                    dr2[tempEnt.Id + "@B"] = tempEnt.Id;
                    dr2[tempEnt.Id + "@C"] = pEnt.ChuangKouBiLi;    //将收款记录的ID存到第二行的第三列上。便于前台获取
                    dr3[tempEnt.Id + "@C"] = tempEnt.ShiJiShouFei;  //第三行收款记录第三列存显示实际收费 即收款金额-收款金额*窗口比例
                    dr4[tempEnt.Id + "@C"] = tempEnt.ChouJinAmount;
                    dr5[tempEnt.Id + "@A"] = tempEnt.YiFenPercent;
                    dr5[tempEnt.Id + "@B"] = 100;
                }
                dt2.Rows.Add(dr1); dt2.Rows.Add(dr2); dt2.Rows.Add(dr3); dt2.Rows.Add(dr4); dt2.Rows.Add(dr5);
                //所有的专家
                IList <Expert> expEnts = Expert.FindAllByProperty(Expert.Prop_SortIndex, Expert.Prop_Status, "T");
                foreach (Expert tEnt in expEnts)
                {
                    DataRow dr = dt2.NewRow();
                    dr["UserId"]      = tEnt.Id;
                    dr["UserName"]    = tEnt.UserName;
                    cjrEnts           = ChouJinResult.FindAllByProperties(ChouJinResult.Prop_ChouJinId, id, ChouJinResult.Prop_ExpertId, tEnt.Id);
                    dr["StageAmount"] = cjrEnts.Count == 0 ? "" : cjrEnts[0].StageAmount + "";
                    foreach (ShouKuan shoukuanEnt in skEnts)
                    {
                        cjdEnts = ChouJinDetail.FindAllByProperties(ChouJinDetail.Prop_ChouJinId, id, ChouJinDetail.Prop_ExpertId, tEnt.Id, ChouJinDetail.Prop_ShouKuanId, shoukuanEnt.Id);
                        IList <ProjectUser> puEnts = ProjectUser.FindAllByProperties(ProjectUser.Prop_ProjectId, shoukuanEnt.ProjectId, ProjectUser.Prop_UserId, tEnt.Id);
                        dr[shoukuanEnt.Id + "@A"] = puEnts.Count > 0 ? "√" : "";
                        dr[shoukuanEnt.Id + "@B"] = cjdEnts.Count > 0 ? cjdEnts[0].ChouJinPercent : null;
                        dr[shoukuanEnt.Id + "@C"] = cjdEnts.Count > 0 ? cjdEnts[0].ChouJinAmount : null;
                    }
                    dt2.Rows.Add(dr);
                }
                Response.Write("{success:true,rows:" + JsonHelper.GetJsonStringFromDataTable(dt2) + "}");
                Response.End();
                break;

            case "savechoujindetail":
                cjdEnts = ChouJinDetail.FindAllByProperties(ChouJinDetail.Prop_ChouJinId, id, ChouJinDetail.Prop_ExpertId, Request["expertid"], ChouJinDetail.Prop_ShouKuanId, Request["shoukuanid"]);
                if (cjdEnts.Count == 0)
                {
                    if (Convert.ToDecimal(Request["choujinpercent"]) > 0)
                    {
                        cjdEnt                = new ChouJinDetail();
                        cjdEnt.ChouJinId      = id;
                        cjdEnt.ExpertId       = Request["expertid"];
                        cjdEnt.UserName       = Request["username"];
                        cjdEnt.ShouKuanId     = Request["shoukuanid"];
                        cjdEnt.ChouJinPercent = Convert.ToDecimal(Request["choujinpercent"]);
                        cjdEnt.ChouJinAmount  = Convert.ToDecimal(Request["choujinamount"]);
                        cjdEnt.IfCanYu        = Request["ifcanyu"];
                        cjdEnt.DoCreate();    //酬金明细保存后,同时更新酬金结果 、收款记录的已分百分比
                        skEnt = ShouKuan.Find(Request["shoukuanid"]);
                        skEnt.YiFenPercent = Convert.ToDecimal(Request["yifenpercent"]);
                        skEnt.DoUpdate();
                    }
                }
                else
                {
                    if (Convert.ToDecimal(Request["choujinpercent"]) > 0)
                    {
                        cjdEnt = cjdEnts[0];
                        cjdEnt.ChouJinPercent = Convert.ToDecimal(Request["choujinpercent"]);
                        cjdEnt.ChouJinAmount  = Convert.ToDecimal(Request["choujinamount"]);
                        cjdEnt.IfCanYu        = Request["ifcanyu"];
                        cjdEnt.DoUpdate();
                        skEnt = ShouKuan.Find(Request["shoukuanid"]);
                        skEnt.YiFenPercent = Convert.ToDecimal(Request["yifenpercent"]);
                        skEnt.DoUpdate();
                    }
                    else
                    {
                        cjdEnts[0].DoDelete();
                    }
                }
                cjrEnts = ChouJinResult.FindAllByProperties(ChouJinResult.Prop_ExpertId, Request["expertid"], ChouJinResult.Prop_ChouJinId, id);
                if (cjrEnts.Count == 0)
                {
                    cjrEnt             = new ChouJinResult();
                    cjrEnt.ExpertId    = Request["expertid"];
                    cjrEnt.UserName    = Request["username"];
                    cjrEnt.ChouJinId   = id;
                    cjrEnt.StageAmount = Convert.ToDecimal(Request["stageamount"]);
                    cjrEnt.DoCreate();
                }
                else
                {
                    if (Convert.ToDecimal(Request["stageamount"]) > 0)
                    {
                        cjrEnt             = cjrEnts[0];
                        cjrEnt.StageAmount = Convert.ToDecimal(Request["stageamount"]);
                        cjrEnt.DoUpdate();
                    }
                    else
                    {
                        cjrEnts[0].DoDelete();
                    }
                }
                break;

            case "loadchoujinresult":    //默认调整金额==分配金额
                sql   = @"select a.Id as ExpertId,a.UserName,b.Remark,b.StageAmount,isnull(AdjustAmount,StageAmount) AdjustAmount from NCRL_SP..Expert a
                          left join (select * from  NCRL_SP..ChouJinResult where ChouJinId='{0}') b on a.Id=b.ExpertId";
                sql   = string.Format(sql, id);
                dt    = DataHelper.QueryDataTable(sql);
                cjEnt = ChouJin.Find(id);
                Response.Write("{rows:" + JsonHelper.GetJsonStringFromDataTable(dt) + ",title:'" + cjEnt.BelongYear + "年" + cjEnt.BelongMonth + "月专家酬金'}");
                Response.End();
                break;

            case "adjustresult":
                cjrEnts = ChouJinResult.FindAllByProperties(ChouJinResult.Prop_ChouJinId, id, ChouJinResult.Prop_ExpertId, Request["expertid"]);
                if (cjrEnts.Count == 0)
                {
                    cjrEnt              = new ChouJinResult();
                    cjrEnt.ExpertId     = Request["expertid"];
                    cjrEnt.UserName     = Request["username"];
                    cjrEnt.ChouJinId    = id;
                    cjrEnt.AdjustAmount = Convert.ToDecimal(Request["adjustamount"]);
                    cjrEnt.Remark       = Request["remark"];
                    cjrEnt.DoCreate();
                }
                else
                {
                    cjrEnt = cjrEnts[0];
                    cjrEnt.AdjustAmount = Convert.ToDecimal(Request["adjustamount"]);
                    cjrEnt.Remark       = Request["remark"];
                    cjrEnt.DoUpdate();
                }
                break;

            case "loadshoukuan_unfenpei":
                sql = @"select a.Id,a.ProjectId,a.InvoiceId,a.ShouKuanAmount,a.ShouKuanDate,a.ShiJiShouFei,
                        a.YiFenPercent,a.ChouJinAmount,b.ProjectName,c.InvoiceNo from NCRL_SP..ShouKuan a                        
                        left join NCRL_SP..Project b on a.ProjectId=b.Id
                        left join NCRL_SP..Invoice c on a.InvoiceId=c.Id
                        where isnull(ChouJinId,'')='' order by a.ShouKuanDate asc";
                dt  = DataHelper.QueryDataTable(sql);
                Response.Write("{rows:" + JsonHelper.GetJsonStringFromDataTable(dt) + "}");
                Response.End();
                break;
            }
        }
Exemple #12
0
        /// <summary>
        /// Verifies that the delegate signature provided in dst can be dynamically mapped to
        /// the method provided by src, with the possible addition of optional parameters set
        /// to their default values.
        /// </summary>
        /// <param name="expected">The method return type and parameter types expected.</param>
        /// <param name="actual">The method to be called.</param>
        /// <returns>The parameters used in the call to the actual method.</returns>
        /// <exception cref="DetourException">If the delegate does not match the target.</exception>
        private static ParameterInfo[] ValidateDelegate(DelegateInfo expected,
                                                        MethodInfo actual)
        {
            var parameterTypes = expected.ParameterTypes;
            var returnType     = expected.ReturnType;

            // Validate return types
            if (!returnType.IsAssignableFrom(actual.ReturnType))
            {
                throw new DetourException("Return type {0} cannot be converted to type {1}".
                                          F(actual.ReturnType.FullName, returnType.FullName));
            }
            // Do not allow methods declared in not yet closed generic types
            var baseType = actual.DeclaringType;

            if (baseType.ContainsGenericParameters)
            {
                throw new DetourException(("Method parent type {0} must have all " +
                                           "generic parameters defined").F(baseType.FullName));
            }
            // Validate parameter types
            string actualName = baseType.FullName + "." + actual.Name;
            var    actualParams = actual.GetParameters();
            int    n = actualParams.Length, check = parameterTypes.Length;

            Type[] actualParamTypes, currentTypes = new Type[n];
            for (int i = 0; i < n; i++)
            {
                currentTypes[i] = actualParams[i].ParameterType;
            }
            if (actual.IsStatic)
            {
                actualParamTypes = currentTypes;
            }
            else
            {
                actualParamTypes = PTranspilerTools.PushDeclaringType(currentTypes, baseType);
                n++;
            }
            if (check > n)
            {
                throw new DetourException(("Method {0} has only {1:D} parameters, but " +
                                           "{2:D} were supplied").F(actual.ToString(), n, check));
            }
            // Check up to the number we have
            for (int i = 0; i < check; i++)
            {
                Type have = actualParamTypes[i], want = parameterTypes[i];
                if (!have.IsAssignableFrom(want))
                {
                    throw new DetourException(("Argument {0:D} for method {3} cannot be " +
                                               "converted from {1} to {2}").F(i, have.FullName, want.FullName,
                                                                              actualName));
                }
            }
            // Any remaining parameters must be optional
            int offset = actual.IsStatic ? 0 : 1;

            for (int i = check; i < n; i++)
            {
                var cParam = actualParams[i - offset];
                if (!cParam.IsOptional)
                {
                    throw new DetourException(("New argument {0:D} for method {1} ({2}) " +
                                               "is not optional").F(i, actualName, cParam.ParameterType.FullName));
                }
            }
            return(actualParams);
        }
Exemple #13
0
        /// <summary>
        /// Creates a dynamic detour method of the specified delegate type to wrap a base game
        /// method with the specified name. The dynamic method will automatically adapt if
        /// optional parameters are added, filling in their default values.
        /// </summary>
        /// <typeparam name="D">The delegate type to be used to call the detour.</typeparam>
        /// <param name="target">The target method to be called.</param>
        /// <returns>The detour that will call that method.</returns>
        /// <exception cref="DetourException">If the delegate does not match the target.</exception>
        public static D Detour <D>(this MethodInfo target) where D : Delegate
        {
            if (target == null)
            {
                throw new ArgumentNullException("target");
            }
            if (target.ContainsGenericParameters)
            {
                throw new ArgumentException("Generic types must have all parameters defined");
            }
            var expected           = DelegateInfo.Create(typeof(D));
            var parentType         = target.DeclaringType;
            var expectedParamTypes = expected.ParameterTypes;
            var actualParams       = ValidateDelegate(expected, target);
            int offset             = target.IsStatic ? 0 : 1;
            // Method will be "declared" in the type of the target, as we are detouring around
            // a method of that type
            var caller = new DynamicMethod(target.Name + "_Detour", expected.ReturnType,
                                           expectedParamTypes, parentType, true);
            var generator = caller.GetILGenerator();
            // Load the known method arguments onto the stack
            int n = expectedParamTypes.Length, need = actualParams.Length + offset;

            if (n > 0)
            {
                generator.Emit(OpCodes.Ldarg_0);
            }
            if (n > 1)
            {
                generator.Emit(OpCodes.Ldarg_1);
            }
            if (n > 2)
            {
                generator.Emit(OpCodes.Ldarg_2);
            }
            if (n > 3)
            {
                generator.Emit(OpCodes.Ldarg_3);
            }
            for (int i = 4; i < n; i++)
            {
                generator.Emit(OpCodes.Ldarg_S, i);
            }
            // Load the rest as defaults
            for (int i = n; i < need; i++)
            {
                var param = actualParams[i - offset];
                PTranspilerTools.GenerateDefaultLoad(generator, param.ParameterType, param.
                                                     DefaultValue);
            }
            if (parentType.IsValueType || target.IsStatic)
            {
                generator.Emit(OpCodes.Call, target);
            }
            else
            {
                generator.Emit(OpCodes.Callvirt, target);
            }
            generator.Emit(OpCodes.Ret);
            // Define the parameter names, parameter indexes start at 1
            if (offset > 0)
            {
                caller.DefineParameter(1, ParameterAttributes.None, "this");
            }
            for (int i = offset; i < n; i++)
            {
                var oldParam = actualParams[i - offset];
                caller.DefineParameter(i + 1, oldParam.Attributes, oldParam.Name);
            }
#if DEBUG
            PUtil.LogDebug("Created delegate {0} for method {1}.{2} with parameters [{3}]".
                           F(caller.Name, parentType.FullName, target.Name, actualParams.Join(",")));
#endif
            return(caller.CreateDelegate(typeof(D)) as D);
        }
Exemple #14
0
        /// <summary>
        /// Компилируем делегат
        /// </summary>
        private static void CompileDelegate <T>(String name, DelegateInfo <T> del)
        {
            // перечисляем все библиотеки, от которых может зависеть текст функции
            String[] referenceAssemblies =
            {
                "System.dll",
                "System.Data.dll",
                "System.Design.dll",
                "System.Drawing.dll",
                "System.Windows.Forms.dll",
                "System.Xml.dll"
            };

            String className = "C" + name + m_classIndex.ToString();

            m_classIndex++;

            // создаем полный текст класса с функцией
            StringBuilder sb = new StringBuilder();

            sb.AppendLine("using System;");
            sb.AppendLine("using System.Data;");
            sb.AppendLine("using System.Text;");
            sb.AppendLine("using System.Design;");
            sb.AppendLine("using System.Drawing;");
            sb.AppendLine("using System.Windows.Forms;");
            sb.AppendLine("using System.Collections.Generic;");
            sb.AppendLine("namespace DelegateGenerator");
            sb.AppendLine("{");
            sb.Append("    public class "); sb.AppendLine(className);
            sb.AppendLine("        {");
            sb.AppendLine(del.Code);
            sb.AppendLine("        }");
            sb.AppendLine("}");

            // компилируем класс

            CompilerParameters codeParams = new CompilerParameters(referenceAssemblies);

            codeParams.GenerateExecutable = false;
            codeParams.GenerateInMemory   = true;
            CSharpCodeProvider codeProvider = new CSharpCodeProvider();
            CompilerResults    codeResult   = codeProvider.CompileAssemblyFromSource(codeParams, sb.ToString());

            // проверяем результат на ошибку
            if (codeResult.Errors.HasErrors)
            {
                StringBuilder err = new StringBuilder();
                for (int i = 0; i < codeResult.Errors.Count; ++i)
                {
                    err.AppendLine(codeResult.Errors[i].ToString());
                }
                del.ErrorText = err.ToString();
                return;
            }

            // получаем функцию созданного класса по имени
            Type type = codeResult.CompiledAssembly.GetType("DelegateGenerator." + className);

            del.MethodInfo = type.GetMethod(name);
            if (null == del.MethodInfo)
            {
                del.ErrorText = String.Format("Delegate name '{0}' error", name);
            }
            else
            {
                del.Delegate = Delegate.CreateDelegate(typeof(T), del.MethodInfo);
                if (null == del.Delegate)
                {
                    del.ErrorText = String.Format("Delegate type '{0}' error", name);
                }
            }
        }
Exemple #15
0
 internal DelegateGetThunkMethodOverride(DelegateInfo delegateInfo)
 {
     _delegateInfo = delegateInfo;
 }
Exemple #16
0
        bool checkProxyMethod(MethodDef method, out DelegateInfo info)
        {
            info = null;
            if (!method.IsStatic || method.Body == null)
            {
                return(false);
            }

            var instrs = method.Body.Instructions;

            if (instrs.Count < 7)
            {
                return(false);
            }

            int index = 0;

            if (instrs[index].OpCode.Code != Code.Ldsfld)
            {
                return(false);
            }
            var field = instrs[index++].Operand as FieldDef;

            if (field == null || !field.IsStatic)
            {
                return(false);
            }
            if (!new SigComparer().Equals(method.DeclaringType, field.DeclaringType))
            {
                return(false);
            }

            if (!instrs[index++].IsBrtrue())
            {
                return(false);
            }
            if (instrs[index++].OpCode.Code != Code.Ldnull)
            {
                return(false);
            }
            if (instrs[index].OpCode.Code != Code.Ldftn)
            {
                return(false);
            }
            var calledMethod = instrs[index++].Operand as IMethod;

            if (calledMethod == null)
            {
                return(false);
            }
            if (instrs[index++].OpCode.Code != Code.Newobj)
            {
                return(false);
            }
            if (instrs[index].OpCode.Code != Code.Stsfld)
            {
                return(false);
            }
            if (!new SigComparer().Equals(field, instrs[index++].Operand as IField))
            {
                return(false);
            }
            if (instrs[index].OpCode.Code != Code.Ldsfld)
            {
                return(false);
            }
            if (!new SigComparer().Equals(field, instrs[index++].Operand as IField))
            {
                return(false);
            }

            var sig = method.MethodSig;

            if (sig == null)
            {
                return(false);
            }
            for (int i = 0; i < sig.Params.Count; i++)
            {
                if (index >= instrs.Count)
                {
                    return(false);
                }
                if (instrs[index++].GetParameterIndex() != i)
                {
                    return(false);
                }
            }

            if (index + 2 > instrs.Count)
            {
                return(false);
            }
            var call = instrs[index++];

            if (call.OpCode.Code != Code.Callvirt)
            {
                return(false);
            }

            if (instrs[index++].OpCode.Code != Code.Ret)
            {
                return(false);
            }

            info = new DelegateInfo(field, calledMethod, OpCodes.Call);
            return(true);
        }
 void add(Dictionary<Block, List<RemoveInfo>> removeInfos, Block block, int index, DelegateInfo di)
 {
     List<RemoveInfo> list;
     if (!removeInfos.TryGetValue(block, out list))
         removeInfos[block] = list = new List<RemoveInfo>();
     list.Add(new RemoveInfo {
         Index = index,
         DelegateInfo = di,
     });
 }
Exemple #18
0
 protected void add(MethodDefinition method, DelegateInfo di)
 {
     proxyMethodToDelegateInfo.add(method, di);
 }
Exemple #19
0
 public DelegateThunk(DelegateInfo delegateInfo)
 {
     _delegateInfo = delegateInfo;
 }
Exemple #20
0
        protected override void EmitCode(NodeFactory factory, ref X64Emitter encoder, bool relocsOnly)
        {
            switch (Id)
            {
            case ReadyToRunHelperId.NewHelper:
            {
                TypeDesc target = (TypeDesc)Target;
                encoder.EmitLEAQ(encoder.TargetRegister.Arg0, factory.ConstructedTypeSymbol(target));
                encoder.EmitJMP(factory.ExternSymbol(JitHelper.GetNewObjectHelperForType(target)));
            }
            break;

            case ReadyToRunHelperId.VirtualCall:
                if (relocsOnly)
                {
                    break;
                }

                AddrMode loadFromThisPtr = new AddrMode(encoder.TargetRegister.Arg0, null, 0, 0, AddrModeSize.Int64);
                encoder.EmitMOV(encoder.TargetRegister.Result, ref loadFromThisPtr);

                {
                    int slot = VirtualMethodSlotHelper.GetVirtualMethodSlot(factory, (MethodDesc)Target);
                    Debug.Assert(slot != -1);
                    AddrMode jmpAddrMode = new AddrMode(encoder.TargetRegister.Result, null, EETypeNode.GetVTableOffset(factory.Target.PointerSize) + (slot * factory.Target.PointerSize), 0, AddrModeSize.Int64);
                    encoder.EmitJmpToAddrMode(ref jmpAddrMode);
                }
                break;

            case ReadyToRunHelperId.IsInstanceOf:
            {
                TypeDesc target = (TypeDesc)Target;
                encoder.EmitLEAQ(encoder.TargetRegister.Arg1, factory.NecessaryTypeSymbol(target));
                encoder.EmitJMP(factory.ExternSymbol(JitHelper.GetCastingHelperNameForType(target, false)));
            }
            break;

            case ReadyToRunHelperId.CastClass:
            {
                TypeDesc target = (TypeDesc)Target;
                encoder.EmitLEAQ(encoder.TargetRegister.Arg1, factory.NecessaryTypeSymbol(target));
                encoder.EmitJMP(factory.ExternSymbol(JitHelper.GetCastingHelperNameForType(target, true)));
            }
            break;

            case ReadyToRunHelperId.NewArr1:
            {
                TypeDesc target = (TypeDesc)Target;


                // TODO: Swap argument order instead
                // mov arg1, arg0
                encoder.Builder.EmitByte(0x48);
                encoder.Builder.EmitShort((short)((encoder.TargetRegister.Arg0 == Register.RCX) ? 0xD18B : 0xF78B));

                encoder.EmitLEAQ(encoder.TargetRegister.Arg0, factory.NecessaryTypeSymbol(target));
                encoder.EmitJMP(factory.ExternSymbol(JitHelper.GetNewArrayHelperForType(target)));
            }
            break;

            case ReadyToRunHelperId.GetNonGCStaticBase:
            {
                MetadataType target = (MetadataType)Target;
                if (!target.HasStaticConstructor)
                {
                    Debug.Assert(Id == ReadyToRunHelperId.GetNonGCStaticBase);
                    encoder.EmitLEAQ(encoder.TargetRegister.Result, factory.TypeNonGCStaticsSymbol(target));
                    encoder.EmitRET();
                }
                else
                {
                    // We need to trigger the cctor before returning the base
                    encoder.EmitLEAQ(encoder.TargetRegister.Arg0, factory.TypeCctorContextSymbol(target));
                    encoder.EmitLEAQ(encoder.TargetRegister.Arg1, factory.TypeNonGCStaticsSymbol(target));
                    encoder.EmitJMP(factory.HelperEntrypoint(HelperEntrypoint.EnsureClassConstructorRunAndReturnNonGCStaticBase));
                }
            }
            break;

            case ReadyToRunHelperId.GetThreadStaticBase:
                encoder.EmitINT3();
                break;

            case ReadyToRunHelperId.GetGCStaticBase:
            {
                MetadataType target = (MetadataType)Target;
                if (!target.HasStaticConstructor)
                {
                    encoder.EmitLEAQ(encoder.TargetRegister.Result, factory.TypeGCStaticsSymbol(target));
                    AddrMode loadFromRax = new AddrMode(encoder.TargetRegister.Result, null, 0, 0, AddrModeSize.Int64);
                    encoder.EmitMOV(encoder.TargetRegister.Result, ref loadFromRax);
                    encoder.EmitMOV(encoder.TargetRegister.Result, ref loadFromRax);
                    encoder.EmitRET();
                }
                else
                {
                    // We need to trigger the cctor before returning the base
                    encoder.EmitLEAQ(encoder.TargetRegister.Arg0, factory.TypeCctorContextSymbol(target));
                    encoder.EmitLEAQ(encoder.TargetRegister.Arg1, factory.TypeGCStaticsSymbol(target));
                    AddrMode loadFromRdx = new AddrMode(encoder.TargetRegister.Arg1, null, 0, 0, AddrModeSize.Int64);
                    encoder.EmitMOV(encoder.TargetRegister.Arg1, ref loadFromRdx);
                    encoder.EmitMOV(encoder.TargetRegister.Arg1, ref loadFromRdx);
                    encoder.EmitJMP(factory.HelperEntrypoint(HelperEntrypoint.EnsureClassConstructorRunAndReturnGCStaticBase));
                }
            }
            break;

            case ReadyToRunHelperId.DelegateCtor:
            {
                DelegateInfo target = (DelegateInfo)Target;

                encoder.EmitLEAQ(encoder.TargetRegister.Arg2, factory.MethodEntrypoint(target.Target));
                if (target.ShuffleThunk != null)
                {
                    encoder.EmitLEAQ(encoder.TargetRegister.Arg3, factory.MethodEntrypoint(target.ShuffleThunk));
                }

                encoder.EmitJMP(factory.MethodEntrypoint(target.Ctor));
            }
            break;

            default:
                throw new NotImplementedException();
            }
        }
        public void find()
        {
            if (delegateCreatorMethods.Count == 0)
                return;

            Log.v("Finding all proxy delegates");
            foreach (var type in module.Types) {
                if (type.BaseType == null || type.BaseType.FullName != "System.MulticastDelegate")
                    continue;
                var cctor = findMethod(type, ".cctor");
                if (cctor == null || !cctor.HasBody)
                    continue;
                if (!type.HasFields)
                    continue;

                object context = checkCctor(type, cctor);
                if (context == null)
                    continue;

                Log.v("Found proxy delegate: {0} ({1:X8})", type, type.MetadataToken.ToUInt32());
                RemovedDelegateCreatorCalls++;
                onFoundProxyDelegate(type);

                Log.indent();
                foreach (var field in type.Fields) {
                    if (!field.IsStatic || field.IsPublic)
                        continue;

                    MethodReference calledMethod;
                    OpCode callOpcode;
                    getCallInfo(context, field, out calledMethod, out callOpcode);

                    if (calledMethod == null)
                        throw new ApplicationException("calledMethod is null");
                    fieldToDelegateInfo[new FieldReferenceAndDeclaringTypeKey(field)] = new DelegateInfo(field, calledMethod, callOpcode);
                    Log.v("Field: {0}, Opcode: {1}, Method: {2} ({3:X8})", field.Name, callOpcode, calledMethod, calledMethod.MetadataToken.ToUInt32());
                }
                Log.deIndent();
                delegateTypesDict[type] = true;
            }
        }
        protected static void Add(Dictionary <Block, List <RemoveInfo> > removeInfos, Block block, int index, DelegateInfo di)
        {
            List <RemoveInfo> list;

            if (!removeInfos.TryGetValue(block, out list))
            {
                removeInfos[block] = list = new List <RemoveInfo>();
            }
            list.Add(new RemoveInfo {
                Index        = index,
                DelegateInfo = di,
            });
        }
Exemple #23
0
 internal DelegateInvokeOpenStaticThunk(DelegateInfo delegateInfo)
     : base(delegateInfo)
 {
 }
 protected void AddDelegateInfo(DelegateInfo di)
 {
     fieldToDelegateInfo.Add(di.field, di);
 }
Exemple #25
0
 public DelegateThunk(DelegateInfo delegateInfo)
 {
     _delegateInfo = delegateInfo;
 }
 protected virtual BlockInstr FindProxyCall(DelegateInfo di, Block block, int index)
 {
     return(FindProxyCall(di, block, index, new Dictionary <Block, bool>(), 1));
 }
Exemple #27
0
 internal DelegateInvokeMulticastThunk(DelegateInfo delegateInfo)
     : base(delegateInfo)
 {
 }
        BlockInstr FindProxyCall(DelegateInfo di, Block block, int index, Dictionary <Block, bool> visited, int stack)
        {
            if (visited.ContainsKey(block))
            {
                return(null);
            }
            if (index <= 0)
            {
                visited[block] = true;
            }

            var instrs = block.Instructions;

            for (int i = index + 1; i < instrs.Count; i++)
            {
                if (stack <= 0)
                {
                    return(null);
                }
                var instr = instrs[i];
                instr.Instruction.UpdateStack(ref stack, false);
                if (stack < 0)
                {
                    return(null);
                }

                if (instr.OpCode != OpCodes.Call && instr.OpCode != OpCodes.Callvirt)
                {
                    if (stack <= 0)
                    {
                        return(null);
                    }
                    continue;
                }
                var calledMethod = instr.Operand as IMethod;
                if (calledMethod == null)
                {
                    return(null);
                }
                if (stack != (DotNetUtils.HasReturnValue(calledMethod) ? 1 : 0))
                {
                    continue;
                }
                if (calledMethod.Name != "Invoke")
                {
                    return(null);
                }

                return(new BlockInstr {
                    Block = block,
                    Index = i,
                });
            }
            if (stack <= 0)
            {
                return(null);
            }

            foreach (var target in block.GetTargets())
            {
                var info = FindProxyCall(di, target, -1, visited, stack);
                if (info != null)
                {
                    return(info);
                }
            }

            return(null);
        }
Exemple #29
0
 internal DelegateReversePInvokeThunk(DelegateInfo delegateInfo)
     : base(delegateInfo)
 {
 }
 protected void Add(MethodDef method, DelegateInfo di)
 {
     proxyMethodToDelegateInfo.Add(method, di);
 }
Exemple #31
0
 public DelegateDynamicInvokeThunk(DelegateInfo delegateInfo)
 {
     _delegateInfo = delegateInfo;
 }
        public void find()
        {
            if (delegateCreatorMethod == null)
                return;

            Log.v("Finding all proxy delegates");
            foreach (var type in module.Types) {
                if (type.BaseType == null || type.BaseType.FullName != "System.MulticastDelegate")
                    continue;
                var cctor = findMethod(type, ".cctor");
                if (cctor == null || !cctor.HasBody)
                    continue;
                if (!type.HasFields)
                    continue;

                var instrs = cctor.Body.Instructions;
                if (instrs.Count != 3)
                    continue;
                if (!DotNetUtils.isLdcI4(instrs[0].OpCode.Code))
                    continue;
                if (instrs[1].OpCode != OpCodes.Call || instrs[1].Operand != delegateCreatorMethod)
                    continue;
                if (instrs[2].OpCode != OpCodes.Ret)
                    continue;

                int delegateToken = 0x02000001 + DotNetUtils.getLdcI4Value(instrs[0]);
                if (type.MetadataToken.ToInt32() != delegateToken) {
                    Log.w("Delegate token is not current type");
                    continue;
                }

                Log.v("Found proxy delegate: {0} ({1:X8})", type, type.MetadataToken.ToUInt32());
                RemovedDelegateCreatorCalls++;
                Log.indent();
                foreach (var field in type.Fields) {
                    if (!field.IsStatic || field.IsPublic)
                        continue;

                    int methodIndex;
                    bool isVirtual;
                    getCallInfo(field, out methodIndex, out isVirtual);
                    if (methodIndex >= memberReferences.Count)
                        throw new ApplicationException(string.Format("methodIndex ({0}) >= memberReferences.Count ({1})", methodIndex, memberReferences.Count));

                    var methodRef = memberReferences[methodIndex] as MethodReference;
                    if (methodRef == null)
                        throw new ApplicationException("methodRef is null");
                    fieldToDelegateInfo[new FieldReferenceAndDeclaringTypeKey(field)] = new DelegateInfo(field, methodRef, isVirtual);
                    Log.v("Field: {0}, Virtual: {1}, Method: {2}, RID: {3}", field.Name, isVirtual, methodRef, methodIndex + 1);
                }
                Log.deIndent();
                delegateTypesDict[type] = true;
            }
        }
 protected void addDelegateInfo(DelegateInfo di)
 {
     fieldToDelegateInfo.add(di.field, di);
 }
Exemple #34
0
 public DelegateDynamicInvokeThunk(DelegateInfo delegateInfo)
 {
     _delegateInfo = delegateInfo;
 }
        BlockInstr findProxyCall(DelegateInfo di, Block block, int index, Dictionary<Block, bool> visited, int stack)
        {
            if (visited.ContainsKey(block))
                return null;
            if (index <= 0)
                visited[block] = true;

            var instrs = block.Instructions;
            for (int i = index + 1; i < instrs.Count; i++) {
                if (stack <= 0)
                    return null;
                var instr = instrs[i];
                DotNetUtils.updateStack(instr.Instruction, ref stack, false);
                if (stack < 0)
                    return null;

                if (instr.OpCode != OpCodes.Call && instr.OpCode != OpCodes.Callvirt)
                    continue;
                var method = DotNetUtils.getMethod(module, instr.Operand as MethodReference);
                if (method == null)
                    continue;
                if (stack != (DotNetUtils.hasReturnValue(method) ? 1 : 0))
                    continue;
                if (method.DeclaringType != di.field.DeclaringType)
                    continue;

                return new BlockInstr {
                    Block = block,
                    Index = i,
                };
            }
            if (stack <= 0)
                return null;

            foreach (var target in block.getTargets()) {
                var info = findProxyCall(di, target, -1, visited, stack);
                if (info != null)
                    return info;
            }

            return null;
        }
    private void CreateAndAssignNewDelegate(DelegateInfo delInfo)
    {
        var method = delInfo.Method;
        var target = delInfo.Target;
        var pTypes = method.GetParameters().Select(x => x.ParameterType).ToArray();
        var args   = new object[pTypes.Length];

        Type delegateType = null;

        if (method.ReturnType == typeof(void))
        {
            if (args.Length == 0)
            {
                delegateType = typeof(Action);
            }
            else if (args.Length == 1)
            {
                delegateType = typeof(Action <>).MakeGenericType(pTypes);
            }
            else if (args.Length == 2)
            {
                delegateType = typeof(Action <,>).MakeGenericType(pTypes);
            }
            else if (args.Length == 3)
            {
                delegateType = typeof(Action <, ,>).MakeGenericType(pTypes);
            }
            else if (args.Length == 4)
            {
                delegateType = typeof(Action <, , ,>).MakeGenericType(pTypes);
            }
            else if (args.Length == 5)
            {
                delegateType = typeof(Action <, , , ,>).MakeGenericType(pTypes);
            }
        }
        else
        {
            pTypes = pTypes.Append(method.ReturnType).ToArray();
            if (args.Length == 0)
            {
                delegateType = typeof(Func <>).MakeArrayType();
            }
            else if (args.Length == 1)
            {
                delegateType = typeof(Func <,>).MakeGenericType(pTypes);
            }
            else if (args.Length == 2)
            {
                delegateType = typeof(Func <, ,>).MakeGenericType(pTypes);
            }
            else if (args.Length == 3)
            {
                delegateType = typeof(Func <, , ,>).MakeGenericType(pTypes);
            }
            else if (args.Length == 4)
            {
                delegateType = typeof(Func <, , , ,>).MakeGenericType(pTypes);
            }
            else if (args.Length == 5)
            {
                delegateType = typeof(Func <, , , , ,>).MakeGenericType(pTypes);
            }
        }

        if (delegateType == null)
        {
            Debug.LogError("Unsupported Method Type");
            return;
        }

        var del = Delegate.CreateDelegate(delegateType, target, method);

        this.Property.Tree.DelayActionUntilRepaint(() =>
        {
            this.ValueEntry.WeakSmartValue = new BetterEventEntry(del);
            GUI.changed = true;
            this.Property.RefreshSetup();
        });
    }
Exemple #37
0
 internal DelegateInvokeClosedStaticThunk(DelegateInfo delegateInfo)
     : base(delegateInfo)
 {
 }
		bool CheckProxyMethod(MethodDef method, out DelegateInfo info) {
			info = null;
			if (!method.IsStatic || method.Body == null)
				return false;

			var instrs = method.Body.Instructions;
			if (instrs.Count < 7)
				return false;

			int index = 0;

			if (instrs[index].OpCode.Code != Code.Ldsfld)
				return false;
			var field = instrs[index++].Operand as FieldDef;
			if (field == null || !field.IsStatic)
				return false;
			if (!new SigComparer().Equals(method.DeclaringType, field.DeclaringType))
				return false;

			if (!instrs[index++].IsBrtrue())
				return false;
			if (instrs[index++].OpCode.Code != Code.Ldnull)
				return false;
			if (instrs[index].OpCode.Code != Code.Ldftn)
				return false;
			var calledMethod = instrs[index++].Operand as IMethod;
			if (calledMethod == null)
				return false;
			if (instrs[index++].OpCode.Code != Code.Newobj)
				return false;
			if (instrs[index].OpCode.Code != Code.Stsfld)
				return false;
			if (!new SigComparer().Equals(field, instrs[index++].Operand as IField))
				return false;
			if (instrs[index].OpCode.Code != Code.Ldsfld)
				return false;
			if (!new SigComparer().Equals(field, instrs[index++].Operand as IField))
				return false;

			var sig = method.MethodSig;
			if (sig == null)
				return false;
			for (int i = 0; i < sig.Params.Count; i++) {
				if (index >= instrs.Count)
					return false;
				if (instrs[index++].GetParameterIndex() != i)
					return false;
			}

			if (index + 2 > instrs.Count)
				return false;
			var call = instrs[index++];
			if (call.OpCode.Code != Code.Callvirt)
				return false;

			if (instrs[index++].OpCode.Code != Code.Ret)
				return false;

			info = new DelegateInfo(field, calledMethod, OpCodes.Call);
			return true;
		}
Exemple #39
0
 internal DelegateInvokeMulticastThunk(DelegateInfo delegateInfo)
     : base(delegateInfo)
 {
 }
Exemple #40
0
 public MyInfo(MethodDefinition method, DelegateInfo delegateInfo)
 {
     this.method = method;
     this.delegateInfo = delegateInfo;
 }
Exemple #41
0
        public DelegateInfo GetDelegateCtor(MethodDesc target)
        {
            DelegateInfo info;

            if (!_delegateInfos.TryGetValue(target, out info))
            {
                _delegateInfos.Add(target, info = new DelegateInfo(this, target));
            }

            return info;
        }
Exemple #42
0
        protected override void EmitCode(NodeFactory factory, ref X64Emitter encoder, bool relocsOnly)
        {
            switch (Id)
            {
            case ReadyToRunHelperId.NewHelper:
                encoder.EmitLEAQ(encoder.TargetRegister.Arg0, factory.ConstructedTypeSymbol((TypeDesc)Target));
                encoder.EmitJMP(factory.ExternSymbol("__allocate_object"));
                break;

            case ReadyToRunHelperId.VirtualCall:
                if (relocsOnly)
                {
                    break;
                }

                AddrMode loadFromThisPtr = new AddrMode(encoder.TargetRegister.Arg0, null, 0, 0, AddrModeSize.Int64);
                encoder.EmitMOV(encoder.TargetRegister.Result, ref loadFromThisPtr);

                {
                    int slot = VirtualMethodSlotHelper.GetVirtualMethodSlot(factory, (MethodDesc)Target);
                    Debug.Assert(slot != -1);
                    AddrMode jmpAddrMode = new AddrMode(encoder.TargetRegister.Result, null, EETypeNode.GetVTableOffset(factory.Target.PointerSize) + (slot * factory.Target.PointerSize), 0, AddrModeSize.Int64);
                    encoder.EmitJmpToAddrMode(ref jmpAddrMode);
                }
                break;

            case ReadyToRunHelperId.IsInstanceOf:
                encoder.EmitLEAQ(encoder.TargetRegister.Arg1, factory.NecessaryTypeSymbol((TypeDesc)Target));
                encoder.EmitJMP(factory.ExternSymbol("__isinst_class"));
                break;

            case ReadyToRunHelperId.CastClass:
                encoder.EmitLEAQ(encoder.TargetRegister.Arg1, factory.NecessaryTypeSymbol((TypeDesc)Target));
                encoder.EmitJMP(factory.ExternSymbol("__castclass_class"));
                break;

            case ReadyToRunHelperId.NewArr1:
                encoder.EmitLEAQ(encoder.TargetRegister.Arg1, factory.NecessaryTypeSymbol((TypeDesc)Target));
                encoder.EmitJMP(factory.ExternSymbol("__allocate_array"));
                break;

            case ReadyToRunHelperId.GetNonGCStaticBase:
                if (!((MetadataType)Target).HasStaticConstructor)
                {
                    Debug.Assert(Id == ReadyToRunHelperId.GetNonGCStaticBase);
                    encoder.EmitLEAQ(encoder.TargetRegister.Result, factory.TypeNonGCStaticsSymbol((MetadataType)Target));
                    encoder.EmitRET();
                }
                else
                {
                    // We need to trigger the cctor before returning the base
                    encoder.EmitLEAQ(encoder.TargetRegister.Arg0, factory.TypeCctorContextSymbol((MetadataType)Target));
                    encoder.EmitLEAQ(encoder.TargetRegister.Arg1, factory.TypeNonGCStaticsSymbol((MetadataType)Target));
                    encoder.EmitJMP(factory.HelperEntrypoint(HelperEntrypoint.EnsureClassConstructorRunAndReturnNonGCStaticBase));
                }
                break;

            case ReadyToRunHelperId.GetThreadStaticBase:
                encoder.EmitINT3();
                break;

            case ReadyToRunHelperId.GetGCStaticBase:
                if (!((MetadataType)Target).HasStaticConstructor)
                {
                    encoder.EmitLEAQ(encoder.TargetRegister.Result, factory.TypeGCStaticsSymbol((MetadataType)Target));
                    AddrMode loadFromRax = new AddrMode(encoder.TargetRegister.Result, null, 0, 0, AddrModeSize.Int64);
                    encoder.EmitMOV(encoder.TargetRegister.Result, ref loadFromRax);
                    encoder.EmitMOV(encoder.TargetRegister.Result, ref loadFromRax);
                    encoder.EmitRET();
                }
                else
                {
                    // We need to trigger the cctor before returning the base
                    encoder.EmitLEAQ(encoder.TargetRegister.Arg0, factory.TypeCctorContextSymbol((MetadataType)Target));
                    encoder.EmitLEAQ(encoder.TargetRegister.Arg1, factory.TypeGCStaticsSymbol((MetadataType)Target));
                    AddrMode loadFromRdx = new AddrMode(encoder.TargetRegister.Arg1, null, 0, 0, AddrModeSize.Int64);
                    encoder.EmitMOV(encoder.TargetRegister.Arg1, ref loadFromRdx);
                    encoder.EmitMOV(encoder.TargetRegister.Arg1, ref loadFromRdx);
                    encoder.EmitJMP(factory.HelperEntrypoint(HelperEntrypoint.EnsureClassConstructorRunAndReturnGCStaticBase));
                }
                break;

            case ReadyToRunHelperId.DelegateCtor:
            {
                DelegateInfo target = (DelegateInfo)Target;

                encoder.EmitLEAQ(encoder.TargetRegister.Arg2, factory.MethodEntrypoint(target.Target));
                if (target.ShuffleThunk != null)
                {
                    encoder.EmitLEAQ(encoder.TargetRegister.Arg3, factory.MethodEntrypoint(target.ShuffleThunk));
                }

                encoder.EmitJMP(factory.MethodEntrypoint(target.Ctor));
            }
            break;

            default:
                throw new NotImplementedException();
            }
        }