Esempio n. 1
0
        private void AnalyzeCodePath(Stack<StackValue> stack, CodePath path, ref int tempVarIndex)
        {
            HLInstruction instruction = path.GetFirstInstruction();
            while (instruction != null)
            {
                try
                {
                    if (instruction.BranchFunction != null)
                    {
                        if (!instruction.Instruction.HasStackUsageInfo)
                        {
                            instruction.Instruction.StackIn = instruction.BranchFunction.ParameterCount;
                            instruction.Instruction.StackOut = instruction.BranchFunction.ReturnCount;
                            instruction.Instruction.StackLeftOver = 0;
                            instruction.Instruction.HasStackUsageInfo = true;
                        }
                    }

                    if (instruction.UnconditionalBranch)
                    {
                        // One should not even occur
                        //Debug.Assert(false);
                    }
                    else if (instruction.ExitFunction)
                    {
                        var value = new StackValueOperation(StackValueOperationType.Return);

                        if (path.ParentFunction.ReturnCount > 0)
                        {
                            for (int i = 0; i < path.ParentFunction.ReturnCount; i++)
                            {
                                value.Operands.Add(stack.Pop());
                            }
                        }

                        instruction.ProcessedStackValue = value;
                    }
                    else if (instruction.IsConditionalBranch || instruction.IsSwitchBranch)
                    {
                        instruction.ProcessedStackValue = stack.Pop();
                    }
                    else
                    {
                        bool processDefault = false;

                        StackValueOperation operationValue = null;
                        StackValue tempAnyValue;
                        StackValueOperation tempOpValue;
                        StackValueLiteral tempLiteralValue;
                        StackValuePointerBase tempPointerValue;

                        OpCode opCode = instruction.Instruction.OpCode;
                        switch (opCode)
                        {
                            case OpCode.AddVec:
                                VectorOperation(StackValueOperationType.Add, stack);
                                break;
                            case OpCode.SubVec:
                                VectorOperation(StackValueOperationType.Sub, stack);
                                break;
                            case OpCode.MulVec:
                                VectorOperation(StackValueOperationType.Mul, stack);
                                break;
                            case OpCode.DivVec:
                                VectorOperation(StackValueOperationType.Div, stack);
                                break;
                            case OpCode.NegVec:
                                VectorOperation(StackValueOperationType.Neg, stack);
                                break;
                            case OpCode.VecFromF:
                                VectorOperation(StackValueOperationType.FromF, stack);
                                break;
                            case OpCode.PushS:
                                stack.Push(new StackValueLiteral((short) instruction.Instruction.Operands[0]));
                                break;
                            case OpCode.Push:
                                stack.Push(new StackValueLiteral((int) (uint) instruction.Instruction.Operands[0]));
                                break;
                            case OpCode.PushF:
                                stack.Push(new StackValueLiteral((float) instruction.Instruction.Operands[0]));
                                break;
                            case OpCode.PushString:
                                stack.Push(new StackValueLiteral((string) instruction.Instruction.Operands[0]));
                                break;
                            case OpCode.Dup:
                                stack.Push(stack.Peek());
                                break;
                            case OpCode.Pop:
                                tempOpValue = stack.Peek() as StackValueOperation;
                                if (tempOpValue != null && tempOpValue.OperationType == StackValueOperationType.Call)
                                {
                                    operationValue = new StackValueOperation(StackValueOperationType.Pop);
                                    processDefault = true;
                                }
                                break;
                            case OpCode.CallNative:
                                operationValue = new StackValueOperation(instruction.Instruction.Operands[2].ToString());
                                processDefault = true;
                                break;
                            case OpCode.Call:
                                operationValue = new StackValueOperation(instruction.BranchFunction.Name);
                                processDefault = true;
                                break;
                            case OpCode.RefGet:
                                stack.Push(new StackValueDeref(stack.Pop()));
                                break;
                            case OpCode.RefSet:
                                instruction.ProcessedStackValue = new StackValueAssign(PopPointer(stack), stack.Pop());
                                break;
                            case OpCode.RefPeekSet:
                                tempAnyValue = stack.Pop(); // value!
                                instruction.ProcessedStackValue = new StackValueAssign(PeekPointer(stack), tempAnyValue);
                                break;
                            case OpCode.ArrayExplode:
                                // This is used to either pass a structure to a native/function call
                                // or to explode the variables onto the stack to do a "shallow-copy"

                                tempPointerValue = PopPointer(stack);
                                tempLiteralValue = stack.Pop() as StackValueLiteral;
                                Debug.Assert(tempLiteralValue != null &&
                                             tempLiteralValue.ValueType == StackValueType.Integer);

                                var explodeCount = (int) tempLiteralValue.Value;
                                for (int i = 0; i < explodeCount; i++)
                                {
                                    stack.Push(new StackValueDeref(new StackValuePointerIndex(tempPointerValue, i)));
                                }

                                break;
                            case OpCode.ArrayImplode:
                                // The only case this is ever used is for a shallow copy!

                                tempPointerValue = PopPointer(stack);
                                tempLiteralValue = stack.Pop() as StackValueLiteral;
                                Debug.Assert(tempLiteralValue != null &&
                                             tempLiteralValue.ValueType == StackValueType.Integer);

                                var tempStack = new Stack<StackValue>();
                                var implodeCount = (int) tempLiteralValue.Value;
                                for (int i = implodeCount - 1; i >= 0; i--)
                                {
                                    tempStack.Push(
                                        new StackValueAssign(new StackValuePointerIndex(tempPointerValue, i),
                                                             stack.Pop()));
                                }

                                var stackValueGroup = new ProcessedStackValueGroup();

                                stackValueGroup.Values.AddRange(tempStack.ToArray());
                                instruction.ProcessedStackValue = stackValueGroup;

                                break;
                            case OpCode.Var0:
                            case OpCode.Var1:
                            case OpCode.Var2:
                            case OpCode.Var3:
                            case OpCode.Var4:
                            case OpCode.Var5:
                            case OpCode.Var6:
                            case OpCode.Var7:
                                stack.Push(new StackValuePointerVar(StackValuePointerType.Stack,
                                                                    (opCode - OpCode.Var0)));
                                break;
                            case OpCode.Var:
                                tempLiteralValue = stack.Pop() as StackValueLiteral;
                                Debug.Assert(tempLiteralValue != null &&
                                             tempLiteralValue.ValueType == StackValueType.Integer);

                                stack.Push(new StackValuePointerVar(StackValuePointerType.Stack,
                                                                    (int) tempLiteralValue.Value));
                                break;
                            case OpCode.LocalVar:
                                tempLiteralValue = stack.Pop() as StackValueLiteral;
                                Debug.Assert(tempLiteralValue != null &&
                                             tempLiteralValue.ValueType == StackValueType.Integer);

                                stack.Push(new StackValuePointerVar(StackValuePointerType.Local,
                                                                    (int) tempLiteralValue.Value));
                                break;
                            case OpCode.GlobalVar:
                                tempLiteralValue = stack.Pop() as StackValueLiteral;
                                Debug.Assert(tempLiteralValue != null &&
                                             tempLiteralValue.ValueType == StackValueType.Integer);

                                stack.Push(new StackValuePointerVar(StackValuePointerType.Global,
                                                                    (int) tempLiteralValue.Value));
                                break;
                            case OpCode.ArrayRef:
                                tempPointerValue = PopPointer(stack);
                                tempLiteralValue = stack.Pop() as StackValueLiteral;
                                tempAnyValue = stack.Pop();
                                Debug.Assert(tempPointerValue != null);
                                Debug.Assert(tempLiteralValue != null &&
                                             tempLiteralValue.ValueType == StackValueType.Integer);

                                stack.Push(new StackValuePointerArray(tempPointerValue, tempAnyValue,
                                                                      (int) tempLiteralValue.Value));
                                break;
                            case OpCode.NullObj:
                                stack.Push(new StackValuePointerVar(StackValuePointerType.Null));
                                break;
                            case OpCode.Add:
                                // Special case for pointer add
                                tempAnyValue = stack.Pop();
                                tempPointerValue = stack.Peek() as StackValuePointerBase;

                                if (tempPointerValue != null)
                                {
                                    stack.Pop(); // tempPointerValue

                                    tempLiteralValue = tempAnyValue as StackValueLiteral;
                                    Debug.Assert(tempLiteralValue != null && (int) tempLiteralValue.Value%4 == 0);

                                    stack.Push(new StackValuePointerIndex(tempPointerValue,
                                                                          (int) tempLiteralValue.Value/4));
                                }
                                else
                                {
                                    stack.Push(tempAnyValue);
                                    operationValue = new StackValueOperation(opCode);
                                    processDefault = true;
                                }
                                break;
                            case OpCode.StrCat:
                            case OpCode.StrCatI:
                            case OpCode.StrCpy:
                            case OpCode.IntToStr:
                                operationValue = new StackValueStringOperation(opCode, (byte)instruction.Instruction.Operands[0]);
                                processDefault = true;
                                break;
                            case OpCode.StrVarCpy:
                                tempPointerValue = PopPointer(stack);

                                tempLiteralValue = stack.Pop() as StackValueLiteral;
                                
                                Debug.Assert(tempLiteralValue != null &&
                                             tempLiteralValue.ValueType == StackValueType.Integer);

                                var targetSize = (uint)(int)tempLiteralValue.Value;

                                tempLiteralValue = stack.Pop() as StackValueLiteral;

                                Debug.Assert(tempLiteralValue != null &&
                                             tempLiteralValue.ValueType == StackValueType.Integer);

                                var sourceSize = (uint)(int)tempLiteralValue.Value;

                                var popSize = sourceSize;

                                tempAnyValue = PopPointer(stack);

                                // Pop till the last one
                                for (var i = 1; i < popSize; i++)
                                {
                                    tempAnyValue = PopPointer(stack);
                                }

                                operationValue = new StackValueStringOperation(opCode, targetSize, sourceSize);
                                operationValue.Operands.Add(new StackValueRef(tempAnyValue)); // 0 = source
                                operationValue.Operands.Add(tempPointerValue); // 1 = target
                                
                                instruction.ProcessedStackValue = operationValue;

                                break;
                            case OpCode.RefProtect:
                                tempLiteralValue = stack.Pop() as StackValueLiteral;

                                Debug.Assert(tempLiteralValue != null &&
                                     tempLiteralValue.ValueType == StackValueType.Integer);

                                var protectMode = (int)tempLiteralValue.Value;

                                Debug.Assert(protectMode == 1 || protectMode == 2 || protectMode == 5 || protectMode == 6);

                                tempLiteralValue = stack.Pop() as StackValueLiteral;

                                Debug.Assert(tempLiteralValue != null &&
                                     tempLiteralValue.ValueType == StackValueType.Integer);

                                var protectCount = (int)tempLiteralValue.Value;

                                //Debug.Assert(protectCount == 1);

                                tempPointerValue = PopPointer(stack);

                                operationValue = new StackValueOperation(StackValueOperationType.RefProtect);
                                operationValue.Operands.Add(tempPointerValue);
                                operationValue.Operands.Add(tempLiteralValue);

                                if ((protectMode & 1) != 0)
                                {
                                    stack.Push(operationValue);
                                }
                                
                                break;
                            default:
                                if (instruction.Instruction is InstructionPush)
                                {
                                    // PushD special case
                                    stack.Push(new StackValueLiteral((int) instruction.Instruction.Operands[0]));
                                }
                                else
                                {
                                    operationValue = new StackValueOperation(opCode);
                                    processDefault = true;
                                }
                                break;
                        }

                        if (processDefault)
                        {
                            Debug.Assert(instruction.Instruction.HasStackUsageInfo);

                            var stackValues = new Stack<StackValue>();
                            for (int i = 0; i < instruction.Instruction.StackIn; i++)
                            {
                                StackValue stackItem = stack.Pop();
                                stackValues.Push(stackItem);
                            }

                            operationValue.Operands.AddRange(stackValues);

                            if (instruction.Instruction.StackLeftOver > 0)
                            {
                                for (int i = 0; i < instruction.Instruction.StackLeftOver; i++)
                                {
                                    stackValues.Push(stackValues.Pop());
                                }
                            }

                            if (instruction.Instruction.StackOut > 0)
                            {
                                if (instruction.Instruction.StackOut > 1)
                                {
                                    var multiAssign = new StackValueAssignMulti(operationValue);
                                    for (int i = 0; i < instruction.Instruction.StackOut; i++)
                                    {
                                        tempPointerValue = new StackValuePointerVar(StackValuePointerType.Temporary,
                                                                                    tempVarIndex + i);
                                        multiAssign.AssignPointers.Add(tempPointerValue);
                                        stack.Push(new StackValueDeref(tempPointerValue));
                                    }
                                    tempVarIndex += instruction.Instruction.StackOut;
                                    instruction.ProcessedStackValue = multiAssign;
                                }
                                else
                                {
                                    stack.Push(operationValue);
                                }
                            }
                            else
                            {
                                instruction.ProcessedStackValue = operationValue;
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    throw new Exception(
                        "Error while decompiling instruction : " + instruction.Instruction + "\n", e);
                }

                instruction = instruction.GetNextInstruction();
            }
        }
Esempio n. 2
0
        private void AnalyzeCodePath(Stack <StackValue> stack, CodePath path, ref int tempVarIndex)
        {
            HLInstruction instruction = path.GetFirstInstruction();

            while (instruction != null)
            {
                try
                {
                    if (instruction.BranchFunction != null)
                    {
                        if (!instruction.Instruction.HasStackUsageInfo)
                        {
                            instruction.Instruction.StackIn           = instruction.BranchFunction.ParameterCount;
                            instruction.Instruction.StackOut          = instruction.BranchFunction.ReturnCount;
                            instruction.Instruction.StackLeftOver     = 0;
                            instruction.Instruction.HasStackUsageInfo = true;
                        }
                    }

                    if (instruction.UnconditionalBranch)
                    {
                        // One should not even occur
                        //Debug.Assert(false);
                    }
                    else if (instruction.ExitFunction)
                    {
                        var value = new StackValueOperation(StackValueOperationType.Return);

                        if (path.ParentFunction.ReturnCount > 0)
                        {
                            for (int i = 0; i < path.ParentFunction.ReturnCount; i++)
                            {
                                value.Operands.Add(stack.Pop());
                            }
                        }

                        instruction.ProcessedStackValue = value;
                    }
                    else if (instruction.IsConditionalBranch || instruction.IsSwitchBranch)
                    {
                        instruction.ProcessedStackValue = stack.Pop();
                    }
                    else
                    {
                        bool processDefault = false;

                        StackValueOperation   operationValue = null;
                        StackValue            tempAnyValue;
                        StackValueOperation   tempOpValue;
                        StackValueLiteral     tempLiteralValue;
                        StackValuePointerBase tempPointerValue;

                        OpCode opCode = instruction.Instruction.OpCode;
                        switch (opCode)
                        {
                        case OpCode.AddVec:
                            VectorOperation(StackValueOperationType.Add, stack);
                            break;

                        case OpCode.SubVec:
                            VectorOperation(StackValueOperationType.Sub, stack);
                            break;

                        case OpCode.MulVec:
                            VectorOperation(StackValueOperationType.Mul, stack);
                            break;

                        case OpCode.DivVec:
                            VectorOperation(StackValueOperationType.Div, stack);
                            break;

                        case OpCode.NegVec:
                            VectorOperation(StackValueOperationType.Neg, stack);
                            break;

                        case OpCode.VecFromF:
                            VectorOperation(StackValueOperationType.FromF, stack);
                            break;

                        case OpCode.PushS:
                            stack.Push(new StackValueLiteral((short)instruction.Instruction.Operands[0]));
                            break;

                        case OpCode.Push:
                            stack.Push(new StackValueLiteral((int)(uint)instruction.Instruction.Operands[0]));
                            break;

                        case OpCode.PushF:
                            stack.Push(new StackValueLiteral((float)instruction.Instruction.Operands[0]));
                            break;

                        case OpCode.PushString:
                            stack.Push(new StackValueLiteral((string)instruction.Instruction.Operands[0]));
                            break;

                        case OpCode.Dup:
                            stack.Push(stack.Peek());
                            break;

                        case OpCode.Pop:
                            tempOpValue = stack.Peek() as StackValueOperation;
                            if (tempOpValue != null && tempOpValue.OperationType == StackValueOperationType.Call)
                            {
                                operationValue = new StackValueOperation(StackValueOperationType.Pop);
                                processDefault = true;
                            }
                            break;

                        case OpCode.CallNative:
                            operationValue = new StackValueOperation(instruction.Instruction.Operands[2].ToString());
                            processDefault = true;
                            break;

                        case OpCode.Call:
                            operationValue = new StackValueOperation(instruction.BranchFunction.Name);
                            processDefault = true;
                            break;

                        case OpCode.RefGet:
                            stack.Push(new StackValueDeref(stack.Pop()));
                            break;

                        case OpCode.RefSet:
                            instruction.ProcessedStackValue = new StackValueAssign(PopPointer(stack), stack.Pop());
                            break;

                        case OpCode.RefPeekSet:
                            tempAnyValue = stack.Pop();     // value!
                            instruction.ProcessedStackValue = new StackValueAssign(PeekPointer(stack), tempAnyValue);
                            break;

                        case OpCode.ArrayExplode:
                            // This is used to either pass a structure to a native/function call
                            // or to explode the variables onto the stack to do a "shallow-copy"

                            tempPointerValue = PopPointer(stack);
                            tempLiteralValue = stack.Pop() as StackValueLiteral;
                            Debug.Assert(tempLiteralValue != null &&
                                         tempLiteralValue.ValueType == StackValueType.Integer);

                            var explodeCount = (int)tempLiteralValue.Value;
                            for (int i = 0; i < explodeCount; i++)
                            {
                                stack.Push(new StackValueDeref(new StackValuePointerIndex(tempPointerValue, i)));
                            }

                            break;

                        case OpCode.ArrayImplode:
                            // The only case this is ever used is for a shallow copy!

                            tempPointerValue = PopPointer(stack);
                            tempLiteralValue = stack.Pop() as StackValueLiteral;
                            Debug.Assert(tempLiteralValue != null &&
                                         tempLiteralValue.ValueType == StackValueType.Integer);

                            var tempStack    = new Stack <StackValue>();
                            var implodeCount = (int)tempLiteralValue.Value;
                            for (int i = implodeCount - 1; i >= 0; i--)
                            {
                                tempStack.Push(
                                    new StackValueAssign(new StackValuePointerIndex(tempPointerValue, i),
                                                         stack.Pop()));
                            }

                            var stackValueGroup = new ProcessedStackValueGroup();

                            stackValueGroup.Values.AddRange(tempStack.ToArray());
                            instruction.ProcessedStackValue = stackValueGroup;

                            break;

                        case OpCode.Var0:
                        case OpCode.Var1:
                        case OpCode.Var2:
                        case OpCode.Var3:
                        case OpCode.Var4:
                        case OpCode.Var5:
                        case OpCode.Var6:
                        case OpCode.Var7:
                            stack.Push(new StackValuePointerVar(StackValuePointerType.Stack,
                                                                (opCode - OpCode.Var0)));
                            break;

                        case OpCode.Var:
                            tempLiteralValue = stack.Pop() as StackValueLiteral;
                            Debug.Assert(tempLiteralValue != null &&
                                         tempLiteralValue.ValueType == StackValueType.Integer);

                            stack.Push(new StackValuePointerVar(StackValuePointerType.Stack,
                                                                (int)tempLiteralValue.Value));
                            break;

                        case OpCode.LocalVar:
                            tempLiteralValue = stack.Pop() as StackValueLiteral;
                            Debug.Assert(tempLiteralValue != null &&
                                         tempLiteralValue.ValueType == StackValueType.Integer);

                            stack.Push(new StackValuePointerVar(StackValuePointerType.Local,
                                                                (int)tempLiteralValue.Value));
                            break;

                        case OpCode.GlobalVar:
                            tempLiteralValue = stack.Pop() as StackValueLiteral;
                            Debug.Assert(tempLiteralValue != null &&
                                         tempLiteralValue.ValueType == StackValueType.Integer);

                            stack.Push(new StackValuePointerVar(StackValuePointerType.Global,
                                                                (int)tempLiteralValue.Value));
                            break;

                        case OpCode.ArrayRef:
                            tempPointerValue = PopPointer(stack);
                            tempLiteralValue = stack.Pop() as StackValueLiteral;
                            tempAnyValue     = stack.Pop();
                            Debug.Assert(tempPointerValue != null);
                            Debug.Assert(tempLiteralValue != null &&
                                         tempLiteralValue.ValueType == StackValueType.Integer);

                            stack.Push(new StackValuePointerArray(tempPointerValue, tempAnyValue,
                                                                  (int)tempLiteralValue.Value));
                            break;

                        case OpCode.NullObj:
                            stack.Push(new StackValuePointerVar(StackValuePointerType.Null));
                            break;

                        case OpCode.Add:
                            // Special case for pointer add
                            tempAnyValue     = stack.Pop();
                            tempPointerValue = stack.Peek() as StackValuePointerBase;

                            if (tempPointerValue != null)
                            {
                                stack.Pop();     // tempPointerValue

                                tempLiteralValue = tempAnyValue as StackValueLiteral;
                                Debug.Assert(tempLiteralValue != null && (int)tempLiteralValue.Value % 4 == 0);

                                stack.Push(new StackValuePointerIndex(tempPointerValue,
                                                                      (int)tempLiteralValue.Value / 4));
                            }
                            else
                            {
                                stack.Push(tempAnyValue);
                                operationValue = new StackValueOperation(opCode);
                                processDefault = true;
                            }
                            break;

                        case OpCode.StrCat:
                        case OpCode.StrCatI:
                        case OpCode.StrCpy:
                        case OpCode.IntToStr:
                            operationValue = new StackValueStringOperation(opCode, (byte)instruction.Instruction.Operands[0]);
                            processDefault = true;
                            break;

                        case OpCode.StrVarCpy:
                            tempPointerValue = PopPointer(stack);

                            tempLiteralValue = stack.Pop() as StackValueLiteral;

                            Debug.Assert(tempLiteralValue != null &&
                                         tempLiteralValue.ValueType == StackValueType.Integer);

                            var targetSize = (uint)(int)tempLiteralValue.Value;

                            tempLiteralValue = stack.Pop() as StackValueLiteral;

                            Debug.Assert(tempLiteralValue != null &&
                                         tempLiteralValue.ValueType == StackValueType.Integer);

                            var sourceSize = (uint)(int)tempLiteralValue.Value;

                            var popSize = sourceSize;

                            tempAnyValue = PopPointer(stack);

                            // Pop till the last one
                            for (var i = 1; i < popSize; i++)
                            {
                                tempAnyValue = PopPointer(stack);
                            }

                            operationValue = new StackValueStringOperation(opCode, targetSize, sourceSize);
                            operationValue.Operands.Add(new StackValueRef(tempAnyValue)); // 0 = source
                            operationValue.Operands.Add(tempPointerValue);                // 1 = target

                            instruction.ProcessedStackValue = operationValue;

                            break;

                        case OpCode.RefProtect:
                            tempLiteralValue = stack.Pop() as StackValueLiteral;

                            Debug.Assert(tempLiteralValue != null &&
                                         tempLiteralValue.ValueType == StackValueType.Integer);

                            var protectMode = (int)tempLiteralValue.Value;

                            Debug.Assert(protectMode == 1 || protectMode == 2 || protectMode == 5 || protectMode == 6);

                            tempLiteralValue = stack.Pop() as StackValueLiteral;

                            Debug.Assert(tempLiteralValue != null &&
                                         tempLiteralValue.ValueType == StackValueType.Integer);

                            var protectCount = (int)tempLiteralValue.Value;

                            //Debug.Assert(protectCount == 1);

                            tempPointerValue = PopPointer(stack);

                            operationValue = new StackValueOperation(StackValueOperationType.RefProtect);
                            operationValue.Operands.Add(tempPointerValue);
                            operationValue.Operands.Add(tempLiteralValue);

                            if ((protectMode & 1) != 0)
                            {
                                stack.Push(operationValue);
                            }

                            break;

                        default:
                            if (instruction.Instruction is InstructionPush)
                            {
                                // PushD special case
                                stack.Push(new StackValueLiteral((int)instruction.Instruction.Operands[0]));
                            }
                            else
                            {
                                operationValue = new StackValueOperation(opCode);
                                processDefault = true;
                            }
                            break;
                        }

                        if (processDefault)
                        {
                            Debug.Assert(instruction.Instruction.HasStackUsageInfo);

                            var stackValues = new Stack <StackValue>();
                            for (int i = 0; i < instruction.Instruction.StackIn; i++)
                            {
                                StackValue stackItem = stack.Pop();
                                stackValues.Push(stackItem);
                            }

                            operationValue.Operands.AddRange(stackValues);

                            if (instruction.Instruction.StackLeftOver > 0)
                            {
                                for (int i = 0; i < instruction.Instruction.StackLeftOver; i++)
                                {
                                    stackValues.Push(stackValues.Pop());
                                }
                            }

                            if (instruction.Instruction.StackOut > 0)
                            {
                                if (instruction.Instruction.StackOut > 1)
                                {
                                    var multiAssign = new StackValueAssignMulti(operationValue);
                                    for (int i = 0; i < instruction.Instruction.StackOut; i++)
                                    {
                                        tempPointerValue = new StackValuePointerVar(StackValuePointerType.Temporary,
                                                                                    tempVarIndex + i);
                                        multiAssign.AssignPointers.Add(tempPointerValue);
                                        stack.Push(new StackValueDeref(tempPointerValue));
                                    }
                                    tempVarIndex += instruction.Instruction.StackOut;
                                    instruction.ProcessedStackValue = multiAssign;
                                }
                                else
                                {
                                    stack.Push(operationValue);
                                }
                            }
                            else
                            {
                                instruction.ProcessedStackValue = operationValue;
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    throw new Exception(
                              "Error while decompiling instruction : " + instruction.Instruction + "\n", e);
                }

                instruction = instruction.GetNextInstruction();
            }
        }