diff --git a/RGiesecke.DllExport/Parsing/Actions/ClassParserAction.cs b/RGiesecke.DllExport/Parsing/Actions/ClassParserAction.cs index c774d23..087012d 100644 --- a/RGiesecke.DllExport/Parsing/Actions/ClassParserAction.cs +++ b/RGiesecke.DllExport/Parsing/Actions/ClassParserAction.cs @@ -53,6 +53,10 @@ public override void Execute(ParserStateValues state, string trimmedLine) } } + /// + /// https://github.com/3F/DllExport/issues/128 + /// https://github.com/3F/DllExport/issues/158 + /// /// /// raw definition of the .field /// true if processed @@ -80,7 +84,31 @@ private bool TreatField(ParserStateValues state, ref string raw) if(m.Success) { - raw = new string(' ', 2) + raw.Substring(0, m.Index) + GetFloatDef(m); + raw = GetInst(raw.Substring(0, m.Index) + GetFloatInfDef(m)); + return true; + } + } + + if((Parser.InputValues.Patches & PatchesType.NaNToken) == PatchesType.NaNToken) + { + // .field public static literal float32 'NaN' = float32(-nan(ind)) + // .field public static literal float64 'NaN' = float64(-nan(ind)) + + Match m = Regex.Match + ( + raw, + @"=\s* + float(?:(?'x64'64)|32) + \( + -nan\(ind\) + \) + ", + RegexOptions.IgnorePatternWhitespace + ); + + if(m.Success) + { + raw = GetInst(raw.Substring(0, m.Index) + GetNaNDef(m)); return true; } } @@ -88,7 +116,7 @@ private bool TreatField(ParserStateValues state, ref string raw) return false; } - private static string GetFloatDef(Match fld) + private static string GetFloatInfDef(Match fld) { var sb = new StringBuilder(4); sb.Append("= float"); @@ -114,5 +142,26 @@ private static string GetFloatDef(Match fld) return sb.ToString(); } + + private static string GetNaNDef(Match fld) + { + var sb = new StringBuilder(3); + sb.Append("= float"); + + if(fld.Groups["x64"].Success) + { + sb.Append("64"); + sb.Append("(0xFFF8000000000000)"); + } + else + { + sb.Append("32"); + sb.Append("(0xFFC00000)"); + } + + return sb.ToString(); + } + + private static string GetInst(string l) => new string(' ', 2) + l; } } diff --git a/RGiesecke.DllExport/Parsing/Actions/MethodParserAction.cs b/RGiesecke.DllExport/Parsing/Actions/MethodParserAction.cs index 3d62fa5..6ac463e 100644 --- a/RGiesecke.DllExport/Parsing/Actions/MethodParserAction.cs +++ b/RGiesecke.DllExport/Parsing/Actions/MethodParserAction.cs @@ -36,6 +36,8 @@ public override void Execute(ParserStateValues state, string trimmedLine) } } + // https://github.com/3F/DllExport/issues/128 + // https://github.com/3F/DllExport/issues/158 private bool TreatIL(ParserStateValues state, ref string raw) { if((Parser.InputValues.Patches & PatchesType.InfToken) == PatchesType.InfToken) @@ -59,7 +61,30 @@ private bool TreatIL(ParserStateValues state, ref string raw) if(m.Success) { - raw = new string(' ', 4) + raw.Substring(0, m.Index) + GetFloatDef(m); + raw = GetInst(raw.Substring(0, m.Index) + GetFloatInfDef(m)); + return true; + } + } + + if((Parser.InputValues.Patches & PatchesType.NaNToken) == PatchesType.NaNToken) + { + // ldc.r8 -nan(ind) + // ldc.r4 -nan(ind) + + Match m = Regex.Match + ( + raw, + @" + ldc.r(?:(?'x64'8)|4) + \s* + -nan\(ind\) + ", + RegexOptions.IgnorePatternWhitespace + ); + + if(m.Success) + { + raw = GetInst(raw.Substring(0, m.Index) + GetNaNDef(m)); return true; } } @@ -67,7 +92,7 @@ private bool TreatIL(ParserStateValues state, ref string raw) return false; } - private static string GetFloatDef(Match fld) + private static string GetFloatInfDef(Match fld) { var sb = new StringBuilder(4); sb.Append("ldc.r"); @@ -93,5 +118,26 @@ private static string GetFloatDef(Match fld) return sb.ToString(); } + + private static string GetNaNDef(Match fld) + { + var sb = new StringBuilder(3); + sb.Append("ldc.r"); + + if(fld.Groups["x64"].Success) + { + sb.Append("8 "); + sb.Append("(00 00 00 00 00 00 F8 FF)"); + } + else + { + sb.Append("4 "); + sb.Append("(00 00 C0 FF)"); + } + + return sb.ToString(); + } + + private static string GetInst(string l) => new string(' ', 4) + l; } } diff --git a/RGiesecke.DllExport/PatchesType.cs b/RGiesecke.DllExport/PatchesType.cs index 175522b..5c6b051 100644 --- a/RGiesecke.DllExport/PatchesType.cs +++ b/RGiesecke.DllExport/PatchesType.cs @@ -20,5 +20,15 @@ public enum PatchesType: long /// https://github.com/3F/DllExport/issues/128 /// InfToken = 0x01, + + /// + /// Affects ldc.r8; ldc.r4; .field; + /// + /// -nan(ind) to 00 00 C0 FF + /// 00 00 00 00 00 00 F8 FF + /// + /// https://github.com/3F/DllExport/issues/158 + /// + NaNToken = 0x02, } } diff --git a/Wizard/UI/Controls/ProjectItemControl.Designer.cs b/Wizard/UI/Controls/ProjectItemControl.Designer.cs index dc045be..75cec09 100644 --- a/Wizard/UI/Controls/ProjectItemControl.Designer.cs +++ b/Wizard/UI/Controls/ProjectItemControl.Designer.cs @@ -28,6 +28,7 @@ private void InitializeComponent() this.rbPlatformAnyCPU = new System.Windows.Forms.RadioButton(); this.rbPlatformX64 = new System.Windows.Forms.RadioButton(); this.groupCompiler = new System.Windows.Forms.GroupBox(); + this.chkNaNPatching = new System.Windows.Forms.CheckBox(); this.linkInfPatching = new System.Windows.Forms.LinkLabel(); this.linkSysObjRebase = new System.Windows.Forms.LinkLabel(); this.chkRebaseSysObj = new System.Windows.Forms.CheckBox(); @@ -185,6 +186,7 @@ private void InitializeComponent() // // groupCompiler // + this.groupCompiler.Controls.Add(this.chkNaNPatching); this.groupCompiler.Controls.Add(this.linkInfPatching); this.groupCompiler.Controls.Add(this.linkSysObjRebase); this.groupCompiler.Controls.Add(this.chkRebaseSysObj); @@ -206,6 +208,18 @@ private void InitializeComponent() this.groupCompiler.TabIndex = 9; this.groupCompiler.TabStop = false; // + // chkNaNPatching + // + this.chkNaNPatching.AutoSize = true; + this.chkNaNPatching.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.chkNaNPatching.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.chkNaNPatching.Location = new System.Drawing.Point(244, 129); + this.chkNaNPatching.Name = "chkNaNPatching"; + this.chkNaNPatching.Size = new System.Drawing.Size(64, 17); + this.chkNaNPatching.TabIndex = 16; + this.chkNaNPatching.Text = "-nan(ind)"; + this.chkNaNPatching.UseVisualStyleBackColor = true; + // // linkInfPatching // this.linkInfPatching.AutoSize = true; @@ -662,5 +676,6 @@ private void InitializeComponent() private System.Windows.Forms.CheckBox chkInfPatching; private System.Windows.Forms.LinkLabel linkInfPatching; private System.Windows.Forms.LinkLabel linkPeCheck; + private System.Windows.Forms.CheckBox chkNaNPatching; } } diff --git a/Wizard/UI/Controls/ProjectItemControl.cs b/Wizard/UI/Controls/ProjectItemControl.cs index b961a7a..bca2957 100644 --- a/Wizard/UI/Controls/ProjectItemControl.cs +++ b/Wizard/UI/Controls/ProjectItemControl.cs @@ -264,9 +264,8 @@ private PatchesType GetPatchesType() { PatchesType patches = PatchesType.None; - if(chkInfPatching.Checked) { - patches |= PatchesType.InfToken; - } + if(chkInfPatching.Checked) { patches |= PatchesType.InfToken; } + if(chkNaNPatching.Checked) { patches |= PatchesType.NaNToken; } return patches; } @@ -274,6 +273,7 @@ private PatchesType GetPatchesType() private void SetPatchesType(PatchesType type) { chkInfPatching.Checked = (type & PatchesType.InfToken) == PatchesType.InfToken; + chkNaNPatching.Checked = (type & PatchesType.NaNToken) == PatchesType.NaNToken; } private void InstalledStatus(bool status)