public static LambdaExpression Decompile(this Delegate @delegate) { var expression = Decompile(@delegate.Method); if (@delegate.Method.IsStatic) { return(expression); } var visitor = new ReplaceExpressionVisitor(new Dictionary <Expression, Expression> { { expression.Parameters[0], Expression.Constant(@delegate.Target) } }); var transformed = visitor.Visit(expression.Body); return(Expression.Lambda(transformed, expression.Parameters.Skip(1))); }
Expression Process() { ProcessorState state = null; while(states.Count > 0) { state = states.Peek(); if(state.RunNext != null) { state.RunNext(); state.RunNext = null; } if(state.Instruction != null && state.Instruction != state.Last) { Debug.WriteLine(state.Instruction); if (state.Instruction.OpCode == OpCodes.Nop || state.Instruction.OpCode == OpCodes.Break) { //do nothing; } else if (state.Instruction.OpCode == OpCodes.Ldtoken) { var runtimeHandle = GetRuntimeHandle(state.Instruction.Operand); state.Stack.Push(Expression.Constant(runtimeHandle)); } else if (state.Instruction.OpCode == OpCodes.Ldarg_0) { LdArg(state, 0); } else if (state.Instruction.OpCode == OpCodes.Ldarg_1) { LdArg(state, 1); } else if (state.Instruction.OpCode == OpCodes.Ldarg_2) { LdArg(state, 2); } else if (state.Instruction.OpCode == OpCodes.Ldarg_3) { LdArg(state, 3); } else if (state.Instruction.OpCode == OpCodes.Ldarg_S || state.Instruction.OpCode == OpCodes.Ldarg || state.Instruction.OpCode == OpCodes.Ldarga || state.Instruction.OpCode == OpCodes.Ldarga_S) { var operand = (ParameterInfo) state.Instruction.Operand; state.Stack.Push(state.Args.Single(x => ((ParameterExpression) x.Expression).Name == operand.Name)); } else if (state.Instruction.OpCode == OpCodes.Ldlen) { var array = state.Stack.Pop(); state.Stack.Push(Expression.ArrayLength(array)); } else if (state.Instruction.OpCode == OpCodes.Ldelem || state.Instruction.OpCode == OpCodes.Ldelem_I || state.Instruction.OpCode == OpCodes.Ldelem_I1 || state.Instruction.OpCode == OpCodes.Ldelem_I2 || state.Instruction.OpCode == OpCodes.Ldelem_I4 || state.Instruction.OpCode == OpCodes.Ldelem_I8 || state.Instruction.OpCode == OpCodes.Ldelem_U1 || state.Instruction.OpCode == OpCodes.Ldelem_U2 || state.Instruction.OpCode == OpCodes.Ldelem_U4 || state.Instruction.OpCode == OpCodes.Ldelem_R4 || state.Instruction.OpCode == OpCodes.Ldelem_R8 || state.Instruction.OpCode == OpCodes.Ldelem_Ref) { var index = state.Stack.Pop(); var array = state.Stack.Pop(); state.Stack.Push(Expression.ArrayIndex(array, index)); } else if (state.Instruction.OpCode == OpCodes.Stloc_0) { StLoc(state, 0); } else if (state.Instruction.OpCode == OpCodes.Stloc_1) { StLoc(state, 1); } else if (state.Instruction.OpCode == OpCodes.Stloc_2) { StLoc(state, 2); } else if (state.Instruction.OpCode == OpCodes.Stloc_3) { StLoc(state, 3); } else if (state.Instruction.OpCode == OpCodes.Stloc_S || state.Instruction.OpCode == OpCodes.Stloc) { var operand = (LocalVariableInfo) state.Instruction.Operand; StLoc(state, operand.LocalIndex); } else if (state.Instruction.OpCode == OpCodes.Stelem || state.Instruction.OpCode == OpCodes.Stelem_I || state.Instruction.OpCode == OpCodes.Stelem_I1 || state.Instruction.OpCode == OpCodes.Stelem_I2 || state.Instruction.OpCode == OpCodes.Stelem_I4 || state.Instruction.OpCode == OpCodes.Stelem_I8 || state.Instruction.OpCode == OpCodes.Stelem_R4 || state.Instruction.OpCode == OpCodes.Stelem_R8 || state.Instruction.OpCode == OpCodes.Stelem_Ref) { StElem(state); } else if (state.Instruction.OpCode == OpCodes.Ldnull) { state.Stack.Push(Expression.Constant(null)); } else if (state.Instruction.OpCode == OpCodes.Ldfld || state.Instruction.OpCode == OpCodes.Ldflda) { var instance = state.Stack.Pop(); state.Stack.Push(Expression.Field(instance, (FieldInfo) state.Instruction.Operand)); } else if (state.Instruction.OpCode == OpCodes.Ldsfld) { var field = (FieldInfo) state.Instruction.Operand; if (IsCachedAnonymousMethodDelegate(field)) { Address address; if (state.Delegates.TryGetValue(field, out address)) { state.Stack.Push(address); } else { state.Stack.Push(Expression.Field(null, field)); } } else { state.Stack.Push(Expression.Field(null, field)); } } else if (state.Instruction.OpCode == OpCodes.Stsfld) { var field = (FieldInfo) state.Instruction.Operand; if (IsCachedAnonymousMethodDelegate(field)) { state.Delegates[field] = state.Stack.Pop(); } else { var pop = state.Stack.Pop(); state.Stack.Push(Expression.Assign(Expression.Field(null, field), pop)); } } else if (state.Instruction.OpCode == OpCodes.Stfld) { var value = state.Stack.Pop(); var instance = state.Stack.Pop(); var field = (FieldInfo)state.Instruction.Operand; var newExpression = instance.Expression as NewExpression; if (newExpression != null) { instance.Expression = Expression.MemberInit(newExpression, Expression.Bind(field, value)); } else { var memberInitExpression = instance.Expression as MemberInitExpression; if (memberInitExpression != null) { var expression = memberInitExpression.NewExpression; var bindings = new List<MemberBinding>(memberInitExpression.Bindings) {Expression.Bind(field, value)}; instance.Expression = Expression.MemberInit(expression, bindings); } else { throw new NotImplementedException(); } } } else if (state.Instruction.OpCode == OpCodes.Ldloc_0) { LdLoc(state, 0); } else if (state.Instruction.OpCode == OpCodes.Ldloc_1) { LdLoc(state, 1); } else if (state.Instruction.OpCode == OpCodes.Ldloc_2) { LdLoc(state, 2); } else if (state.Instruction.OpCode == OpCodes.Ldloc_3) { LdLoc(state, 3); } else if (state.Instruction.OpCode == OpCodes.Ldloc || state.Instruction.OpCode == OpCodes.Ldloc_S || state.Instruction.OpCode == OpCodes.Ldloca || state.Instruction.OpCode == OpCodes.Ldloca_S) { var operand = (LocalVariableInfo) state.Instruction.Operand; LdLoc(state, operand.LocalIndex); } else if (state.Instruction.OpCode == OpCodes.Ldstr) { state.Stack.Push(Expression.Constant((string) state.Instruction.Operand)); } else if (state.Instruction.OpCode == OpCodes.Ldc_I4_0) { LdC(state, 0); } else if (state.Instruction.OpCode == OpCodes.Ldc_I4_1) { LdC(state, 1); } else if (state.Instruction.OpCode == OpCodes.Ldc_I4_2) { LdC(state, 2); } else if (state.Instruction.OpCode == OpCodes.Ldc_I4_3) { LdC(state, 3); } else if (state.Instruction.OpCode == OpCodes.Ldc_I4_4) { LdC(state, 4); } else if (state.Instruction.OpCode == OpCodes.Ldc_I4_5) { LdC(state, 5); } else if (state.Instruction.OpCode == OpCodes.Ldc_I4_6) { LdC(state, 6); } else if (state.Instruction.OpCode == OpCodes.Ldc_I4_7) { LdC(state, 7); } else if (state.Instruction.OpCode == OpCodes.Ldc_I4_8) { LdC(state, 8); } else if (state.Instruction.OpCode == OpCodes.Ldc_I4_S) { LdC(state, (sbyte)state.Instruction.Operand); } else if (state.Instruction.OpCode == OpCodes.Ldc_I4_M1) { LdC(state, -1); } else if (state.Instruction.OpCode == OpCodes.Ldc_I4) { LdC(state, (int)state.Instruction.Operand); } else if (state.Instruction.OpCode == OpCodes.Ldc_I8) { LdC(state, (long)state.Instruction.Operand); } else if (state.Instruction.OpCode == OpCodes.Ldc_R4) { LdC(state, (float)state.Instruction.Operand); } else if (state.Instruction.OpCode == OpCodes.Ldc_R8) { LdC(state, (double)state.Instruction.Operand); } else if (state.Instruction.OpCode == OpCodes.Br_S || state.Instruction.OpCode == OpCodes.Br) { state.Instruction = (Instruction) state.Instruction.Operand; continue; } else if (state.Instruction.OpCode == OpCodes.Brfalse || state.Instruction.OpCode == OpCodes.Brfalse_S) { state.Instruction = ConditionalBranch(state, val => Expression.Equal(val, Default(val.Type))); continue; } else if (state.Instruction.OpCode == OpCodes.Brtrue || state.Instruction.OpCode == OpCodes.Brtrue_S) { var address = state.Stack.Peek(); var memberExpression = address.Expression as MemberExpression; if (memberExpression != null && IsCachedAnonymousMethodDelegate(memberExpression.Member as FieldInfo)) { state.Stack.Pop(); } else { state.Instruction = ConditionalBranch(state, val => Expression.NotEqual(val, Default(val.Type))); continue; } } else if (state.Instruction.OpCode == OpCodes.Ldftn) { var method = (MethodInfo) state.Instruction.Operand; var decompile = method.Decompile(); var obj = state.Stack.Pop(); if (!method.IsStatic) { var expressions = new Dictionary<Expression, Expression> { {decompile.Parameters[0], obj} }; var body = new ReplaceExpressionVisitor(expressions).Visit(decompile.Body); body = TransparentIdentifierRemovingExpressionVisitor.RemoveTransparentIdentifiers(body); decompile = Expression.Lambda(body, decompile.Parameters.Skip(1)); } state.Stack.Push(decompile); state.Instruction = state.Instruction.Next; } else if (state.Instruction.OpCode == OpCodes.Bgt || state.Instruction.OpCode == OpCodes.Bgt_S || state.Instruction.OpCode == OpCodes.Bgt_Un || state.Instruction.OpCode == OpCodes.Bgt_Un_S) { var val1 = state.Stack.Pop(); state.Instruction = ConditionalBranch(state, val => Expression.GreaterThan(val, val1)); continue; } else if (state.Instruction.OpCode == OpCodes.Bge || state.Instruction.OpCode == OpCodes.Bge_S || state.Instruction.OpCode == OpCodes.Bge_Un || state.Instruction.OpCode == OpCodes.Bge_Un_S) { var val1 = state.Stack.Pop(); state.Instruction = ConditionalBranch(state, val => Expression.GreaterThanOrEqual(val, val1)); continue; } else if (state.Instruction.OpCode == OpCodes.Blt || state.Instruction.OpCode == OpCodes.Blt_S || state.Instruction.OpCode == OpCodes.Blt_Un || state.Instruction.OpCode == OpCodes.Blt_Un_S) { var val1 = state.Stack.Pop(); state.Instruction = ConditionalBranch(state, val => Expression.LessThan(val, val1)); continue; } else if (state.Instruction.OpCode == OpCodes.Ble || state.Instruction.OpCode == OpCodes.Ble_S || state.Instruction.OpCode == OpCodes.Ble_Un || state.Instruction.OpCode == OpCodes.Ble_Un_S) { var val1 = state.Stack.Pop(); state.Instruction = ConditionalBranch(state, val => Expression.LessThanOrEqual(val, val1)); continue; } else if (state.Instruction.OpCode == OpCodes.Beq || state.Instruction.OpCode == OpCodes.Beq_S) { var val1 = state.Stack.Pop(); state.Instruction = ConditionalBranch(state, val => AdjustedBinaryExpression(val, val1, ExpressionType.Equal)); continue; } else if (state.Instruction.OpCode == OpCodes.Bne_Un || state.Instruction.OpCode == OpCodes.Bne_Un_S) { var val1 = state.Stack.Pop(); state.Instruction = ConditionalBranch(state, val => AdjustedBinaryExpression(val, val1, ExpressionType.NotEqual)); continue; } else if (state.Instruction.OpCode == OpCodes.Dup) { state.Stack.Push(state.Stack.Peek()); } else if (state.Instruction.OpCode == OpCodes.Pop) { state.Stack.Pop(); } else if (state.Instruction.OpCode == OpCodes.Add) { var val1 = state.Stack.Pop(); var val2 = state.Stack.Pop(); state.Stack.Push(AdjustedBinaryExpression(val2, AdjustBooleanConstant(val1, val2.Type), ExpressionType.Add)); } else if (state.Instruction.OpCode == OpCodes.Add_Ovf || state.Instruction.OpCode == OpCodes.Add_Ovf_Un) { var val1 = state.Stack.Pop(); var val2 = state.Stack.Pop(); state.Stack.Push(AdjustedBinaryExpression(val2, AdjustBooleanConstant(val1, val2.Type), ExpressionType.AddChecked)); } else if (state.Instruction.OpCode == OpCodes.Sub) { var val1 = state.Stack.Pop(); var val2 = state.Stack.Pop(); state.Stack.Push(AdjustedBinaryExpression(val2, AdjustBooleanConstant(val1, val2.Type), ExpressionType.Subtract)); } else if (state.Instruction.OpCode == OpCodes.Sub_Ovf || state.Instruction.OpCode == OpCodes.Sub_Ovf_Un) { var val1 = state.Stack.Pop(); var val2 = state.Stack.Pop(); state.Stack.Push(AdjustedBinaryExpression(val2, AdjustBooleanConstant(val1, val2.Type), ExpressionType.SubtractChecked)); } else if (state.Instruction.OpCode == OpCodes.Mul) { var val1 = state.Stack.Pop(); var val2 = state.Stack.Pop(); state.Stack.Push(AdjustedBinaryExpression(val2, AdjustBooleanConstant(val1, val2.Type), ExpressionType.Multiply)); } else if (state.Instruction.OpCode == OpCodes.Mul_Ovf || state.Instruction.OpCode == OpCodes.Mul_Ovf_Un) { var val1 = state.Stack.Pop(); var val2 = state.Stack.Pop(); state.Stack.Push(AdjustedBinaryExpression(val2, AdjustBooleanConstant(val1, val2.Type), ExpressionType.MultiplyChecked)); } else if (state.Instruction.OpCode == OpCodes.Div || state.Instruction.OpCode == OpCodes.Div_Un) { var val1 = state.Stack.Pop(); var val2 = state.Stack.Pop(); state.Stack.Push(AdjustedBinaryExpression(val2, AdjustBooleanConstant(val1, val2.Type), ExpressionType.Divide)); } else if (state.Instruction.OpCode == OpCodes.Rem || state.Instruction.OpCode == OpCodes.Rem_Un) { var val1 = state.Stack.Pop(); var val2 = state.Stack.Pop(); state.Stack.Push(AdjustedBinaryExpression(val2, AdjustBooleanConstant(val1, val2.Type), ExpressionType.Modulo)); } else if (state.Instruction.OpCode == OpCodes.Xor) { var val1 = state.Stack.Pop(); var val2 = state.Stack.Pop(); state.Stack.Push(AdjustedBinaryExpression(val2, AdjustBooleanConstant(val1, val2.Type), ExpressionType.ExclusiveOr)); } else if (state.Instruction.OpCode == OpCodes.Shl) { var val1 = state.Stack.Pop(); var val2 = state.Stack.Pop(); state.Stack.Push(AdjustedBinaryExpression(val2, AdjustBooleanConstant(val1, val2.Type), ExpressionType.LeftShift)); } else if (state.Instruction.OpCode == OpCodes.Shr || state.Instruction.OpCode == OpCodes.Shr_Un) { var val1 = state.Stack.Pop(); var val2 = state.Stack.Pop(); state.Stack.Push(AdjustedBinaryExpression(val2, AdjustBooleanConstant(val1, val2.Type), ExpressionType.RightShift)); } else if (state.Instruction.OpCode == OpCodes.Neg) { var val = state.Stack.Pop(); state.Stack.Push(Expression.Negate(val)); } else if (state.Instruction.OpCode == OpCodes.Not) { var val = state.Stack.Pop(); state.Stack.Push(Expression.Not(val)); } else if (state.Instruction.OpCode == OpCodes.Conv_I) { var val1 = state.Stack.Pop(); state.Stack.Push(Expression.Convert(val1, typeof (int))); // Support x64? } else if (state.Instruction.OpCode == OpCodes.Conv_I1) { var val1 = state.Stack.Pop(); state.Stack.Push(Expression.Convert(val1, typeof (sbyte))); } else if (state.Instruction.OpCode == OpCodes.Conv_I2) { var val1 = state.Stack.Pop(); state.Stack.Push(Expression.Convert(val1, typeof (short))); } else if (state.Instruction.OpCode == OpCodes.Conv_I4) { var val1 = state.Stack.Pop(); state.Stack.Push(Expression.Convert(val1, typeof (int))); } else if (state.Instruction.OpCode == OpCodes.Conv_I8) { var val1 = state.Stack.Pop(); state.Stack.Push(Expression.Convert(val1, typeof (long))); } else if (state.Instruction.OpCode == OpCodes.Conv_U) { var val1 = state.Stack.Pop(); state.Stack.Push(Expression.Convert(val1, typeof (uint))); // Suppot x64? } else if (state.Instruction.OpCode == OpCodes.Conv_U1) { var val1 = state.Stack.Pop(); state.Stack.Push(Expression.Convert(val1, typeof (byte))); } else if (state.Instruction.OpCode == OpCodes.Conv_U2) { var val1 = state.Stack.Pop(); state.Stack.Push(Expression.Convert(val1, typeof (ushort))); } else if (state.Instruction.OpCode == OpCodes.Conv_U4) { var val1 = state.Stack.Pop(); state.Stack.Push(Expression.Convert(val1, typeof (uint))); } else if (state.Instruction.OpCode == OpCodes.Conv_U8) { var val1 = state.Stack.Pop(); state.Stack.Push(Expression.Convert(val1, typeof (ulong))); } else if (state.Instruction.OpCode == OpCodes.Conv_Ovf_I || state.Instruction.OpCode == OpCodes.Conv_Ovf_I_Un) { var val1 = state.Stack.Pop(); state.Stack.Push(Expression.ConvertChecked(val1, typeof (int))); // Suppot x64? } else if (state.Instruction.OpCode == OpCodes.Conv_Ovf_I1 || state.Instruction.OpCode == OpCodes.Conv_Ovf_I1_Un) { var val1 = state.Stack.Pop(); state.Stack.Push(Expression.ConvertChecked(val1, typeof (sbyte))); } else if (state.Instruction.OpCode == OpCodes.Conv_Ovf_I2 || state.Instruction.OpCode == OpCodes.Conv_Ovf_I2_Un) { var val1 = state.Stack.Pop(); state.Stack.Push(Expression.ConvertChecked(val1, typeof (short))); } else if (state.Instruction.OpCode == OpCodes.Conv_Ovf_I4 || state.Instruction.OpCode == OpCodes.Conv_Ovf_I4_Un) { var val1 = state.Stack.Pop(); state.Stack.Push(Expression.ConvertChecked(val1, typeof (int))); } else if (state.Instruction.OpCode == OpCodes.Conv_Ovf_I8 || state.Instruction.OpCode == OpCodes.Conv_Ovf_I8_Un) { var val1 = state.Stack.Pop(); state.Stack.Push(Expression.ConvertChecked(val1, typeof (long))); } else if (state.Instruction.OpCode == OpCodes.Conv_Ovf_U || state.Instruction.OpCode == OpCodes.Conv_Ovf_U_Un) { var val1 = state.Stack.Pop(); state.Stack.Push(Expression.ConvertChecked(val1, typeof (uint))); // Suppot x64? } else if (state.Instruction.OpCode == OpCodes.Conv_Ovf_U1 || state.Instruction.OpCode == OpCodes.Conv_Ovf_U1_Un) { var val1 = state.Stack.Pop(); state.Stack.Push(Expression.ConvertChecked(val1, typeof (byte))); } else if (state.Instruction.OpCode == OpCodes.Conv_Ovf_U2 || state.Instruction.OpCode == OpCodes.Conv_Ovf_U2_Un) { var val1 = state.Stack.Pop(); state.Stack.Push(Expression.ConvertChecked(val1, typeof (ushort))); } else if (state.Instruction.OpCode == OpCodes.Conv_Ovf_U4 || state.Instruction.OpCode == OpCodes.Conv_Ovf_U4_Un) { var val1 = state.Stack.Pop(); state.Stack.Push(Expression.ConvertChecked(val1, typeof (uint))); } else if (state.Instruction.OpCode == OpCodes.Conv_Ovf_U8 || state.Instruction.OpCode == OpCodes.Conv_Ovf_U8_Un) { var val1 = state.Stack.Pop(); state.Stack.Push(Expression.ConvertChecked(val1, typeof (ulong))); } else if (state.Instruction.OpCode == OpCodes.Conv_R4 || state.Instruction.OpCode == OpCodes.Conv_R_Un) { var val1 = state.Stack.Pop(); state.Stack.Push(Expression.ConvertChecked(val1, typeof (float))); } else if (state.Instruction.OpCode == OpCodes.Conv_R8) { var val1 = state.Stack.Pop(); state.Stack.Push(Expression.ConvertChecked(val1, typeof (double))); } else if (state.Instruction.OpCode == OpCodes.Castclass) { var val1 = state.Stack.Pop(); state.Stack.Push(Expression.Convert(val1, (Type) state.Instruction.Operand)); } else if (state.Instruction.OpCode == OpCodes.And) { var val1 = state.Stack.Pop(); var val2 = state.Stack.Pop(); state.Stack.Push(Expression.And(val2, val1)); } else if (state.Instruction.OpCode == OpCodes.Or) { var val1 = state.Stack.Pop(); var val2 = state.Stack.Pop(); state.Stack.Push(Expression.Or(val2, val1)); } else if (state.Instruction.OpCode == OpCodes.Newobj) { var constructor = (ConstructorInfo) state.Instruction.Operand; state.Stack.Push(Expression.New(constructor, GetArguments(state, constructor))); } else if (state.Instruction.OpCode == OpCodes.Initobj) { var address = state.Stack.Pop(); var type = (Type) state.Instruction.Operand; address.Expression = Default(type); } else if (state.Instruction.OpCode == OpCodes.Newarr) { var operand = (Type) state.Instruction.Operand; var expression = state.Stack.Pop(); var size = expression.Expression as ConstantExpression; if (size != null && (int) size.Value == 0) // optimization state.Stack.Push(Expression.NewArrayInit(operand)); else state.Stack.Push(Expression.NewArrayBounds(operand, expression)); } else if (state.Instruction.OpCode == OpCodes.Box) { state.Stack.Push(Box(state.Stack.Pop(), (Type) state.Instruction.Operand)); } else if (state.Instruction.OpCode == OpCodes.Call || state.Instruction.OpCode == OpCodes.Callvirt) { Call(state, (MethodInfo)state.Instruction.Operand); } else if (state.Instruction.OpCode == OpCodes.Ceq) { var val1 = state.Stack.Pop(); var val2 = state.Stack.Pop(); state.Stack.Push(AdjustedBinaryExpression(val2, AdjustBooleanConstant(val1, val2.Type), ExpressionType.Equal)); } else if (state.Instruction.OpCode == OpCodes.Cgt || state.Instruction.OpCode == OpCodes.Cgt_Un) { var val1 = state.Stack.Pop(); var val2 = state.Stack.Pop(); state.Stack.Push(AdjustedBinaryExpression(val2, AdjustBooleanConstant(val1, val2.Type), ExpressionType.GreaterThan)); } else if (state.Instruction.OpCode == OpCodes.Clt || state.Instruction.OpCode == OpCodes.Clt_Un) { var val1 = state.Stack.Pop(); var val2 = state.Stack.Pop(); state.Stack.Push(AdjustedBinaryExpression(val2, AdjustBooleanConstant(val1, val2.Type), ExpressionType.LessThan)); } else if (state.Instruction.OpCode == OpCodes.Isinst) { var val = state.Stack.Pop(); if (state.Instruction.Next != null && state.Instruction.Next.OpCode == OpCodes.Ldnull && state.Instruction.Next.Next != null && state.Instruction.Next.Next.OpCode == OpCodes.Cgt_Un) { state.Stack.Push(Expression.TypeIs(val, (Type) state.Instruction.Operand)); state.Instruction = state.Instruction.Next.Next; } else { state.Stack.Push(Expression.TypeAs(val, (Type) state.Instruction.Operand)); } } else if (state.Instruction.OpCode == OpCodes.Ret) { states.Pop(); } else { Debug.WriteLine("Unhandled!!!"); } state.Instruction = state.Instruction.Next; } else { states.Pop(); } } return state == null ? Expression.Empty() : state.Final(); }