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 @@ -166,7 +166,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
}
context.Step("Translate fields to local accesses", function);
TranslateFieldsToLocalAccess(function, function, fieldToParameterMap);
TranslateFieldsToLocalAccess(function, function, fieldToParameterMap, isCompiledWithMono);
CleanSkipFinallyBodies(function);
@ -823,7 +823,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -823,7 +823,7 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
/// <summary>
/// Translates all field accesses in `function` to local variable accesses.
/// </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()) {
var fieldDef = (IField)ldflda.Field.MemberDefinition;
@ -845,11 +845,11 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow @@ -845,11 +845,11 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
} else {
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 });
} else {
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) {
LdLoc ldloc = new LdLoc(ldloca.Variable);

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

@ -47,7 +47,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -47,7 +47,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
ILFunction f = TransformDelegateConstruction(call, out ILInstruction target);
if (f != null) {
call.ReplaceWith(f);
if (target is IInstructionWithVariableOperand && !target.MatchLdThis())
if (target is IInstructionWithVariableOperand)
targetsToReplace.Add((IInstructionWithVariableOperand)target);
}
}
@ -269,6 +269,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -269,6 +269,8 @@ namespace ICSharpCode.Decompiler.IL.Transforms
protected internal override void VisitStLoc(StLoc inst)
{
base.VisitStLoc(inst);
if (targetLoad is ILInstruction instruction && instruction.MatchLdThis())
return;
if (inst.Variable == targetLoad.Variable)
orphanedVariableInits.Add(inst);
if (MatchesTargetOrCopyLoad(inst.Value)) {
@ -285,7 +287,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -285,7 +287,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
protected internal override void VisitStObj(StObj 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;
field = (IField)field.MemberDefinition;
ILInstruction value;
@ -321,6 +323,11 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -321,6 +323,11 @@ namespace ICSharpCode.Decompiler.IL.Transforms
protected internal override void VisitLdFlda(LdFlda 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)
return;
if (!MatchesTargetOrCopyLoad(inst.Target))

Loading…
Cancel
Save