Browse Source

Fix delegate in yield return issue for assembly compiled with Mono

pull/1303/head
Wenxuan Zhao 7 years ago
parent
commit
3e937cf7cb
No known key found for this signature in database
GPG Key ID: B45B13F10587A57
  1. 8
      ICSharpCode.Decompiler/IL/ControlFlow/YieldReturnDecompiler.cs
  2. 11
      ICSharpCode.Decompiler/IL/Transforms/DelegateConstruction.cs

8
ICSharpCode.Decompiler/IL/ControlFlow/YieldReturnDecompiler.cs

@ -166,7 +166,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
} }
context.Step("Translate fields to local accesses", function); context.Step("Translate fields to local accesses", function);
TranslateFieldsToLocalAccess(function, function, fieldToParameterMap); TranslateFieldsToLocalAccess(function, function, fieldToParameterMap, isCompiledWithMono);
CleanSkipFinallyBodies(function); CleanSkipFinallyBodies(function);
@ -823,7 +823,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
/// <summary> /// <summary>
/// Translates all field accesses in `function` to local variable accesses. /// Translates all field accesses in `function` to local variable accesses.
/// </summary> /// </summary>
internal static void TranslateFieldsToLocalAccess(ILFunction function, ILInstruction inst, Dictionary<IField, ILVariable> fieldToVariableMap) internal static void TranslateFieldsToLocalAccess(ILFunction function, ILInstruction inst, Dictionary<IField, ILVariable> fieldToVariableMap, bool isCompiledWithMono = false)
{ {
if (inst is LdFlda ldflda && ldflda.Target.MatchLdThis()) { if (inst is LdFlda ldflda && ldflda.Target.MatchLdThis()) {
var fieldDef = (IField)ldflda.Field.MemberDefinition; var fieldDef = (IField)ldflda.Field.MemberDefinition;
@ -845,11 +845,11 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
} else { } else {
inst.ReplaceWith(new LdLoca(v) { ILRange = inst.ILRange }); inst.ReplaceWith(new LdLoca(v) { ILRange = inst.ILRange });
} }
} else if (inst.MatchLdThis()) { } else if (!isCompiledWithMono && inst.MatchLdThis()) {
inst.ReplaceWith(new InvalidExpression("stateMachine") { ExpectedResultType = inst.ResultType, ILRange = inst.ILRange }); inst.ReplaceWith(new InvalidExpression("stateMachine") { ExpectedResultType = inst.ResultType, ILRange = inst.ILRange });
} else { } else {
foreach (var child in inst.Children) { foreach (var child in inst.Children) {
TranslateFieldsToLocalAccess(function, child, fieldToVariableMap); TranslateFieldsToLocalAccess(function, child, fieldToVariableMap, isCompiledWithMono);
} }
if (inst is LdObj ldobj && ldobj.Target is LdLoca ldloca && ldloca.Variable.StateMachineField != null) { if (inst is LdObj ldobj && ldobj.Target is LdLoca ldloca && ldloca.Variable.StateMachineField != null) {
LdLoc ldloc = new LdLoc(ldloca.Variable); LdLoc ldloc = new LdLoc(ldloca.Variable);

11
ICSharpCode.Decompiler/IL/Transforms/DelegateConstruction.cs

@ -47,7 +47,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
ILFunction f = TransformDelegateConstruction(call, out ILInstruction target); ILFunction f = TransformDelegateConstruction(call, out ILInstruction target);
if (f != null) { if (f != null) {
call.ReplaceWith(f); call.ReplaceWith(f);
if (target is IInstructionWithVariableOperand && !target.MatchLdThis()) if (target is IInstructionWithVariableOperand)
targetsToReplace.Add((IInstructionWithVariableOperand)target); targetsToReplace.Add((IInstructionWithVariableOperand)target);
} }
} }
@ -269,6 +269,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms
protected internal override void VisitStLoc(StLoc inst) protected internal override void VisitStLoc(StLoc inst)
{ {
base.VisitStLoc(inst); base.VisitStLoc(inst);
if (targetLoad is ILInstruction instruction && instruction.MatchLdThis())
return;
if (inst.Variable == targetLoad.Variable) if (inst.Variable == targetLoad.Variable)
orphanedVariableInits.Add(inst); orphanedVariableInits.Add(inst);
if (MatchesTargetOrCopyLoad(inst.Value)) { if (MatchesTargetOrCopyLoad(inst.Value)) {
@ -285,7 +287,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
protected internal override void VisitStObj(StObj inst) protected internal override void VisitStObj(StObj inst)
{ {
base.VisitStObj(inst); base.VisitStObj(inst);
if (!inst.Target.MatchLdFlda(out ILInstruction target, out IField field) || !MatchesTargetOrCopyLoad(target)) if (!inst.Target.MatchLdFlda(out ILInstruction target, out IField field) || !MatchesTargetOrCopyLoad(target) || target.MatchLdThis())
return; return;
field = (IField)field.MemberDefinition; field = (IField)field.MemberDefinition;
ILInstruction value; ILInstruction value;
@ -321,6 +323,11 @@ namespace ICSharpCode.Decompiler.IL.Transforms
protected internal override void VisitLdFlda(LdFlda inst) protected internal override void VisitLdFlda(LdFlda inst)
{ {
base.VisitLdFlda(inst); base.VisitLdFlda(inst);
if (inst.Target.MatchLdThis() && inst.Field.Name == "$this"
&& inst.Field.MemberDefinition.ReflectionName.Contains("c__Iterator")) {
var variable = currentFunction.Variables.First((f) => f.Index == -1);
inst.ReplaceWith(new LdLoca(variable) { ILRange = inst.ILRange });
}
if (inst.Parent is LdObj || inst.Parent is StObj) if (inst.Parent is LdObj || inst.Parent is StObj)
return; return;
if (!MatchesTargetOrCopyLoad(inst.Target)) if (!MatchesTargetOrCopyLoad(inst.Target))

Loading…
Cancel
Save