Exemple #1
0
        private MethodCallEffect BuildMethodCallEffect(Instruction instruction, CallKind callKind)
        {
            var methodOperand      = (IMethod)instruction.Operand;
            var parameterCount     = methodOperand.GetParameterCount();
            var symbolicParameters = new SymbolicSlot[parameterCount];

            for (int i = parameterCount - 1; i >= 0; i--)
            {
                symbolicParameters[i] = context.Frame.Pop();
            }

            var          signature       = methodOperand.MethodSig;
            SymbolicSlot symbolicRetSlot = null;

            if (!IsSystemVoid(signature.RetType))
            {
                symbolicRetSlot = new SymbolicSlot(
                    new SymbolicReference(
                        new MethodReturnSource(methodOperand)));
                context.Frame.Push(symbolicRetSlot);
            }

            return(new MethodCallEffect(
                       methodOperand,
                       symbolicParameters,
                       symbolicRetSlot,
                       callKind));
        }
Exemple #2
0
        private MethodCallEffect BuildCtorCallEffect(Instruction instruction)
        {
            var methodOperand      = (IMethod)instruction.Operand;
            var signature          = methodOperand.MethodSig;
            var parameterCount     = methodOperand.GetParameterCount();
            var symbolicParameters = new SymbolicSlot[parameterCount];
            var lastParameter      = signature.ImplicitThis ? 1 : 0;

            for (int i = parameterCount - 1; i >= lastParameter; i--)
            {
                symbolicParameters[i] = context.Frame.Pop();
            }

            var thisReturnValue =
                new SymbolicSlot(
                    new SymbolicReference(
                        new MethodReturnSource(methodOperand)));

            if (signature.ImplicitThis)
            {
                symbolicParameters[0] = thisReturnValue;
            }

            context.Frame.Push(thisReturnValue);
            return(new CtorCallEffect(
                       methodOperand,
                       symbolicParameters,
                       thisReturnValue));
        }
Exemple #3
0
        public void Store(int id, SymbolicSlot newSlot)
        {
            if (newSlot.IsConstAfterSimplification())
            {
                return;
            }

            slots[id] = SymbolicSlot.Merge(slots[id], newSlot);
        }
        public override SymbolicSlot Load(int id, string name = null)
        {
            if (!Slots.TryGetValue(id, out var slot))
            {
                slot = new SymbolicSlot(new SymbolicReference(new UninitializedValueSource($"Var {id}")));
                Slots.Add(id, slot);
            }

            return(slot);
        }
 public void AddReturnValue(SymbolicSlot value)
 {
     if (returnValue == null)
     {
         returnValue = value;
     }
     else
     {
         returnValue = SymbolicSlot.Merge(returnValue, value);
     }
 }
Exemple #6
0
        public override SymbolicSlot Load(string id, string name = null)
        {
            if (!Slots.TryGetValue(id, out var slot))
            {
                slot = new SymbolicSlot(new SymbolicReference(new StaticFieldSource(id)));
                Slots.Add(id, slot);
                return(slot);
            }

            return(slot);
        }
Exemple #7
0
        public static StackFrame Merge(StackFrame firstFrame, StackFrame secondFrame)
        {
            if (firstFrame.slots.Count != secondFrame.slots.Count)
            {
                throw new Exception("Not support merging StackFrames with different slot count");
            }

            var newSlots = new List <SymbolicSlot>(firstFrame.slots.Count);

            for (int i = 0; i < firstFrame.slots.Count; i++)
            {
                newSlots.Add(SymbolicSlot.Merge(firstFrame.slots[i], secondFrame.slots[i]));
            }

            return(new StackFrame(newSlots));
        }
        public ExecutionContext(ImmutableStack <string> callStack, MethodUniqueSignature signature, MethodDef method,
                                bool enableStaticFields, bool markInputArguments)
        {
            this.method             = method;
            this.enableStaticFields = enableStaticFields;
            CallStack = callStack;
            Signature = signature;

            staticEntity = new SymbolicReference();
            Static       = new SymbolicSlot(staticEntity);

            var countArguments = method.GetParameterCount();

            Arguments        = new ArgumentContext(signature, countArguments, markInputArguments);
            InstructionCount = method.HasBody ? (double)method.Body.Instructions.Count : 0;
        }
Exemple #9
0
        public ArgumentContext(MethodUniqueSignature signature, int count, bool markInput)
        {
            this.count = count;
            root       = new SymbolicReference();
            slots      = new SymbolicSlot[count];
            for (int id = 0; id < count; id++)
            {
                var entity = new SymbolicReference(new ArgumentSource(id, signature));
                if (markInput)
                {
                    entity.MarkInput();
                }

                root.StoreField(SymbolicReference.ArgumentPrefix + id, entity);
                slots[id] = new SymbolicSlot(entity);
            }
        }
Exemple #10
0
        public MethodCallEffect(
            IMethod method,
            SymbolicSlot[] symbolicParameters, SymbolicSlot symbolicRetSlot,
            CallKind callKind)
            : base(method.CreateMethodUniqueSignature(), method.ResolveMethodDef(), symbolicParameters, callKind)
        {
            OutputSlots = new List <SymbolicSlot>(method.MethodSig.Params.Count + 1);
            if (symbolicRetSlot != null)
            {
                OutputSlots.Add(symbolicRetSlot);
            }

            foreach (var index in method.EnumerateOutputParameterIndexes())
            {
                OutputSlots.Add(symbolicParameters[index]);
            }
        }
Exemple #11
0
        private (IEffect, int) Interpret(int currentIndex)
        {
            var instruction = method.Body.Instructions[currentIndex];

            switch (instruction.OpCode.Code)
            {
            case Code.Add:
            case Code.Add_Ovf:
            case Code.Add_Ovf_Un:
            case Code.Sub:
            case Code.Sub_Ovf:
            case Code.Sub_Ovf_Un:     // CHECK arithmetic operations
            {
                FakeUpdateFrame(instruction);
                break;
                // implemented because they can be used for pointers
                var value2 = context.Frame.Pop();
                var value1 = context.Frame.Pop();

                var value1ContainsNotConst = value1.ContainsNotConst();
                var value2ContainsNotConst = value2.ContainsNotConst();
                if (value1ContainsNotConst && !value2ContainsNotConst)
                {
                    context.Frame.Push(value1);
                }
                else if (!value1ContainsNotConst && value2ContainsNotConst)
                {
                    context.Frame.Push(value2);
                }
                else if (value1ContainsNotConst && value2ContainsNotConst)
                {
                    //context.Frame.Push(SymbolicSlot.Merge(value1, value2));
                    //Console.WriteLine("Add/sub two not constants (lose tracing vars)!");
                    context.Frame.Push(value1);
                }
                else
                {
                    context.Frame.Push(ExecutionContext.FakeSymbolicValue);
                }

                break;
            }

            case Code.And:
            case Code.Arglist:        // CHECK
                FakeUpdateFrame(instruction);
                break;

            case Code.Beq:
            case Code.Bge:
            case Code.Bge_Un:
            case Code.Bgt:
            case Code.Bgt_Un:
            case Code.Ble:
            case Code.Ble_Un:
            case Code.Blt:
            case Code.Blt_Un:
            case Code.Bne_Un:
            {
                FakeUpdateFrame(instruction);
                var(firstFrame, secondFrame) = context.Frame.Fork();
                var jumpIndex = AddCondition(
                    (Instruction)instruction.Operand,
                    currentIndex,
                    firstFrame);
                context.Frame = secondFrame;
                return(null, jumpIndex);
            }

            case Code.Box:        // CHECK ref
                // now ignore any transformation like cast-op
                break;

            case Code.Br:
            {
                var jumpIndex = AddCondition(
                    (Instruction)instruction.Operand,
                    currentIndex,
                    context.Frame);
                EnableSkipMode();
                return(null, jumpIndex);
            }

            case Code.Break:     // CHECK
                break;

            case Code.Brfalse:
            {
                // Transfers control to a target instruction if value is false, a null reference, or zero
                FakeUpdateFrame(instruction);
                var(firstFrame, secondFrame) = context.Frame.Fork();
                var jumpIndex = AddCondition(
                    (Instruction)instruction.Operand,
                    currentIndex,
                    firstFrame);
                context.Frame = secondFrame;
                return(null, jumpIndex);
            }

            case Code.Brtrue:
            {
                // Transfers control to a target instruction if value is true, not null, or non-zero
                FakeUpdateFrame(instruction);
                var(firstFrame, secondFrame) = context.Frame.Fork();
                var jumpIndex = AddCondition(
                    (Instruction)instruction.Operand,
                    currentIndex,
                    firstFrame);
                context.Frame = secondFrame;
                return(null, jumpIndex);
            }

            case Code.Call:
                // need to add order number for the effect
                return(BuildMethodCallEffect(instruction, CallKind.Concrete), 0);

            case Code.Calli:
                throw new Exception($"Not supported calli opcode {method.Module} {method} ({instruction})");
                // https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.calli
                break;

            case Code.Callvirt:
            {
                var callKind      = CallKind.Virtual;
                var methodOperand = ((IMethod)instruction.Operand).ResolveMethodDef();
                if (methodOperand != null && !methodOperand.IsVirtual)
                {
                    Debug.Assert(!methodOperand.IsAbstract);
                    callKind = CallKind.Concrete;
                }

                return(BuildMethodCallEffect(instruction, callKind), 0);
            }

            case Code.Castclass:        // CHECK implement later!
                // don't change a frame stack to keep tainted symbolic value in the stack
                break;

            case Code.Ceq:
            case Code.Cgt:
            case Code.Cgt_Un:
                FakeUpdateFrame(instruction);
                break;

            case Code.Ckfinite:
                // Throws ArithmeticException if value is not a finite number
                // don't change a frame stack to keep tainted symbolic value in the stack
                break;

            case Code.Clt:
            case Code.Clt_Un:
                FakeUpdateFrame(instruction);
                break;

            case Code.Constrained:
                // see Code.Callvirt
                FakeUpdateFrame(instruction);
                break;

            case Code.Conv_I:
            case Code.Conv_I1:
            case Code.Conv_I2:
            case Code.Conv_I4:
            case Code.Conv_I8:
            case Code.Conv_Ovf_I:
            case Code.Conv_Ovf_I_Un:
            case Code.Conv_Ovf_I1:
            case Code.Conv_Ovf_I1_Un:
            case Code.Conv_Ovf_I2:
            case Code.Conv_Ovf_I2_Un:
            case Code.Conv_Ovf_I4:
            case Code.Conv_Ovf_I4_Un:
            case Code.Conv_Ovf_I8:
            case Code.Conv_Ovf_I8_Un:
            case Code.Conv_Ovf_U:
            case Code.Conv_Ovf_U_Un:
            case Code.Conv_Ovf_U1:
            case Code.Conv_Ovf_U1_Un:
            case Code.Conv_Ovf_U2:
            case Code.Conv_Ovf_U2_Un:
            case Code.Conv_Ovf_U4:
            case Code.Conv_Ovf_U4_Un:
            case Code.Conv_Ovf_U8:
            case Code.Conv_Ovf_U8_Un:
            case Code.Conv_R_Un:
            case Code.Conv_R4:
            case Code.Conv_R8:
            case Code.Conv_U:
            case Code.Conv_U1:
            case Code.Conv_U2:
            case Code.Conv_U4:
            case Code.Conv_U8:
                // pop value, convert to a certain type, and push onto the stack
                // just ignore converting and information about types for now
                break;

            case Code.Cpblk:        // CHECK add stat
                // Copies a specified number bytes from a source address to a destination address
                FakeUpdateFrame(instruction);
                break;

            case Code.Cpobj:        // CHECK add stat
                // Copies the value type located at the address of an object (type &, or native int) to the address of the destination object (type &, or native int).
                FakeUpdateFrame(instruction);
                break;

            case Code.Div:
            case Code.Div_Un:
                FakeUpdateFrame(instruction);
                break;

            case Code.Dup:        // CHECK for value types (need clone SymbolicObject?)
                context.Frame.Push(context.Frame.Peek());
                break;

            case Code.Endfilter:
                // TODO:
                //Transfers control from the filter clause of an exception back to the CLI exception handler.
                break;

            case Code.Endfinally:
                // TODO:
                // Transfers control from the fault or finally clause of an exception block back to the CLI exception handler.
                break;

            case Code.Initblk:
                // Initializes a specified block of memory at a specific address to a given size and initial value.
                FakeUpdateFrame(instruction);
                break;

            case Code.Initobj:
                // Initializes each field of the value type at a specified address to a null reference or a 0 of the appropriate primitive type
                FakeUpdateFrame(instruction);
                break;

            case Code.Isinst:        // CHECK cast
                // Tests whether an object reference (type O) is an instance of a particular class.
                FakeUpdateFrame(instruction);
                break;

            case Code.Jmp:
                // TODO: like a call with exit semantic
                // Exits current method and jumps to specified method
                break;

            case Code.Ldarga:        // CHECK ref
            case Code.Ldarg:
                var argument = (Parameter)instruction.Operand;
                if (IsSimple(argument.Type))
                {
                    FakeUpdateFrame(instruction);
                    break;
                }

                context.Frame.Push(
                    context.Arguments.Load(
                        argument.Index,
                        argument.Name));
                break;

            case Code.Ldc_I4:
            case Code.Ldc_I8:
            case Code.Ldc_R4:
            case Code.Ldc_R8:
                FakeUpdateFrame(instruction);
                break;

            case Code.Ldelem:
            case Code.Ldelem_I:
            case Code.Ldelem_I1:
            case Code.Ldelem_I2:
            case Code.Ldelem_I4:
            case Code.Ldelem_I8:
            case Code.Ldelem_R4:
            case Code.Ldelem_R8:
            case Code.Ldelem_Ref:
            case Code.Ldelem_U1:
            case Code.Ldelem_U2:
            case Code.Ldelem_U4:
            case Code.Ldelema:     // CHECK array
            {
                var index  = context.Frame.Pop();
                var target = context.Frame.Pop();
                if (target.IsConstAfterSimplification())
                {
                    context.Frame.Push(ExecutionContext.FakeSymbolicValue);
                    break;
                }

                context.Frame.Push(target.LoadField(SymbolicReference.ArrayElement));
                break;
            }

            case Code.Ldflda:        // CHECK ref
            case Code.Ldfld:
            {
                var operand = (IField)instruction.Operand;
                if (IsSimple(operand.FieldSig.Type))
                {
                    FakeUpdateFrame(instruction);
                    break;
                }

                var target = context.Frame.Pop();
                context.Frame.Push(
                    target.LoadField(((IFullName)instruction.Operand).Name));        //FieldDefMD
                break;
            }

            case Code.Ldftn:
                FakeUpdateFrame(instruction);
                break;

            case Code.Ldind_I:
            case Code.Ldind_I1:
            case Code.Ldind_I2:
            case Code.Ldind_I4:
            case Code.Ldind_I8:
            case Code.Ldind_R4:
            case Code.Ldind_R8:
            case Code.Ldind_Ref:
            case Code.Ldind_U1:
            case Code.Ldind_U2:
            case Code.Ldind_U4:
            case Code.Ldobj:        // CHECK ref
            {
                // do nothing because we have the same symbolic object for address and value
                // see a stack semantic by https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.ldobj?view=netframework-4.8
                break;
            }

            case Code.Ldlen:            //CHECK array
                FakeUpdateFrame(instruction);
                break;

            case Code.Ldloca:     // ref
            case Code.Ldloc:
            {
                var operand = (Local)instruction.Operand;
                if (IsSimple(operand.Type))
                {
                    FakeUpdateFrame(instruction);
                    break;
                }

                context.Frame.Push(
                    context.Variables.Load(operand.Index));
                break;
            }

            case Code.Ldnull:
                context.Frame.Push(ExecutionContext.SymbolicNull);
                break;

            case Code.Ldsflda:     // ref
            case Code.Ldsfld:
            {
                var operand = (IField)instruction.Operand;
                if (IsSimple(operand.FieldSig.Type))
                {
                    FakeUpdateFrame(instruction);
                    break;
                }

                context.Frame.Push(
                    context.Static.LoadField(
                        ((IFullName)instruction.Operand).FullName.Split(' ')[1]));      //FieldDefMD
                break;
            }

            case Code.Ldstr:
                context.Frame.Push(
                    new SymbolicSlot(
                        new SymbolicReference(
                            new ConstSource((string)instruction.Operand))));
                break;

            case Code.Ldtoken:        // reflection
                FakeUpdateFrame(instruction);
                break;

            case Code.Ldvirtftn:        // for calli
                FakeUpdateFrame(instruction);
                break;

            case Code.Leave:     // CHECK try/catch
            {
                // temporary solution: skipping catch-block as a code after br-opcode
                var jumpIndex = AddCondition((Instruction)instruction.Operand,
                                             currentIndex,
                                             context.Frame);
                // TODO: Debug.Assert(jumpIndex == 0);
                EnableSkipMode();
                break;
            }

            case Code.Localloc:
                FakeUpdateFrame(instruction);
                break;

            case Code.Mkrefany:        // ref?
                FakeUpdateFrame(instruction);
                break;

            case Code.Mul:
            case Code.Mul_Ovf:
            case Code.Mul_Ovf_Un:
            case Code.Neg:
                // ignore any calculation of build-in types
                FakeUpdateFrame(instruction);
                break;

            case Code.Newarr:
            {
                var count       = context.Frame.Pop();
                var arrayObject =
                    new SymbolicSlot(
                        new SymbolicReference(
                            new NewArraySource(((IFullName)instruction.Operand).FullName)));
                context.Frame.Push(arrayObject);
                break;
            }

            case Code.Newobj:
                return(BuildCtorCallEffect(instruction), 0);

            case Code.Nop:
                break;

            case Code.Not:
            case Code.Or:
                // logic operators
                FakeUpdateFrame(instruction);
                break;

            case Code.Pop:
                context.Frame.Pop();
                break;

            case Code.Readonly:        // CHECK ldelema
                FakeUpdateFrame(instruction);
                break;

            case Code.Refanytype:        // CHECK reflection??
                FakeUpdateFrame(instruction);
                break;

            case Code.Refanyval:        // CHECK reflection??
                FakeUpdateFrame(instruction);
                break;

            case Code.Rem:
            case Code.Rem_Un:
                FakeUpdateFrame(instruction);
                break;

            case Code.Ret:
            {
                if (method.HasReturnType)
                {
                    var value = context.Frame.Pop();
                    if (!value.IsConstAfterSimplification() &&
                        !IsSimple(method.ReturnType))
                    {
                        context.AddReturnValue(value);
                    }
                }

                EnableSkipMode();
                break;
            }

            case Code.Rethrow:
                FakeUpdateFrame(instruction);
                EnableSkipMode();
                break;

            case Code.Shl:
            case Code.Shr:
            case Code.Shr_Un:
                FakeUpdateFrame(instruction);
                break;

            case Code.Sizeof:
                FakeUpdateFrame(instruction);
                break;

            case Code.Starg:
            {
                var operand = (Parameter)instruction.Operand;
                if (IsSimple(operand.Type))
                {
                    FakeUpdateFrame(instruction);
                    break;
                }

                context.Arguments.Store(
                    operand.Index,
                    context.Frame.Pop());
                break;
            }

            case Code.Stelem:     // CHECK array
            case Code.Stelem_I:
            case Code.Stelem_I1:
            case Code.Stelem_I2:
            case Code.Stelem_I4:
            case Code.Stelem_I8:
            case Code.Stelem_R4:
            case Code.Stelem_R8:
            case Code.Stelem_Ref:     // CHECK ref
            {
                var value  = context.Frame.Pop();
                var index  = context.Frame.Pop();
                var target = context.Frame.Pop();
                //if (value.IsSimpleConst)
                //    break;

                target.StoreField(SymbolicReference.ArrayElement, value);
                break;
            }

            case Code.Stfld:
            {
                var value   = context.Frame.Pop();
                var target  = context.Frame.Pop();
                var operand = (IField)instruction.Operand;
                if (IsSimple(operand.FieldSig.Type))
                {
                    break;
                }

                /*
                 * // HACK DBNull
                 * // the method System.Net.HttpWebRequest::GetResponse()
                 * // executes too much time w/o this restriction
                 * // IsTainted() runs much times
                 * if (value.ToString().EndsWith("Static[System.DBNull::Value]"))
                 *  break;
                 */

                target.StoreField(operand.Name, value);
                break;
            }

            case Code.Stind_I:
            case Code.Stind_I1:
            case Code.Stind_I2:
            case Code.Stind_I4:
            case Code.Stind_I8:
            case Code.Stind_R4:
            case Code.Stind_R8:
            case Code.Stind_Ref:
            case Code.Stobj:         // CHECK ref
            {
                var value   = context.Frame.Pop();
                var address = context.Frame.Pop();
                address.Store(value);
                break;
            }

            case Code.Stloc:
            {
                var operand = (Local)instruction.Operand;
                if (IsSimple(operand.Type))
                {
                    FakeUpdateFrame(instruction);
                    break;
                }

                context.Variables.Store(
                    operand.Index,
                    context.Frame.Pop());
                break;
            }

            case Code.Stsfld:
            {
                var value   = context.Frame.Pop();
                var operand = (IField)instruction.Operand;
                if (IsSimple(operand.FieldSig.Type))
                {
                    break;
                }

                context.Static.StoreField(
                    operand.FullName.Split(' ')[1],
                    value);
                break;
            }

            case Code.Switch:
                FakeUpdateFrame(instruction);
                var currentFrame = context.Frame;
                var instructions = (Instruction[])instruction.Operand;
                for (var i = instructions.Length - 1; i >= 0; i--)
                {
                    Context.StackFrame firstFrame;
                    (firstFrame, currentFrame) = currentFrame.Fork();
                    var jumpIndex = AddCondition(
                        instructions[i],
                        currentIndex,
                        firstFrame);
                    //TODO: Debug.Assert(jumpIndex == 0);
                }

                context.Frame = currentFrame;
                break;

            case Code.Tailcall:        // call
                FakeUpdateFrame(instruction);
                break;

            case Code.Throw:
                FakeUpdateFrame(instruction);
                EnableSkipMode();
                break;

            case Code.Unaligned:        // unmanaged
                FakeUpdateFrame(instruction);
                break;

            case Code.Unbox:        // Check boxing
            case Code.Unbox_Any:
                break;

            case Code.Volatile:        // CHECK ???
                FakeUpdateFrame(instruction);
                break;

            case Code.Xor:        // CHECK logic operations
                FakeUpdateFrame(instruction);
                break;

            case Code.Beq_S:
            case Code.Bge_S:
            case Code.Bge_Un_S:
            case Code.Bgt_S:
            case Code.Bgt_Un_S:
            case Code.Ble_S:
            case Code.Ble_Un_S:
            case Code.Blt_S:
            case Code.Blt_Un_S:
            case Code.Bne_Un_S:
            case Code.Br_S:
            case Code.Brfalse_S:
            case Code.Brtrue_S:
            case Code.Ldarg_0:
            case Code.Ldarg_1:
            case Code.Ldarg_2:
            case Code.Ldarg_3:
            case Code.Ldarg_S:
            case Code.Ldarga_S:
            case Code.Ldc_I4_0:
            case Code.Ldc_I4_1:
            case Code.Ldc_I4_2:
            case Code.Ldc_I4_3:
            case Code.Ldc_I4_4:
            case Code.Ldc_I4_5:
            case Code.Ldc_I4_6:
            case Code.Ldc_I4_7:
            case Code.Ldc_I4_8:
            case Code.Ldc_I4_M1:
            case Code.Ldc_I4_S:
            case Code.Ldloc_0:
            case Code.Ldloc_1:
            case Code.Ldloc_2:
            case Code.Ldloc_3:
            case Code.Ldloc_S:
            case Code.Ldloca_S:
            case Code.Leave_S:
            case Code.Starg_S:
            case Code.Stloc_0:
            case Code.Stloc_1:
            case Code.Stloc_2:
            case Code.Stloc_3:
            case Code.Stloc_S:
                throw new NotSupportedException($"Must be simplified {instruction.OpCode.Code}");

            case Code.UNKNOWN1:
            case Code.UNKNOWN2:
            case Code.Prefix1:
            case Code.Prefix2:
            case Code.Prefix3:
            case Code.Prefix4:
            case Code.Prefix5:
            case Code.Prefix6:
            case Code.Prefix7:
            case Code.Prefixref:
                //This is a reserved instruction.
                throw new NotSupportedException($"Not supported {instruction.OpCode.Code}");

            default:
                throw new ArgumentOutOfRangeException();
            }

            return(null, 0);
        }
Exemple #12
0
 public void Push(SymbolicSlot value)
 {
     slots.Add(value);
 }
        public void Apply(Summary summary, SymbolicSlot[] parameters, DataFlowAnalysisResult result,
                          ReturnValueApplyingMode returnValueApplying, string indent = "")
        {
            //return;
            if (summary.IsEmpty)
            {
                return;
            }

            MethodCallCount  += summary.MethodCallCount;
            InstructionCount += summary.InstructionCount;

            Debug.Assert(summary.Arguments.Length == parameters.Length);
            if (summary.Arguments.Length != parameters.Length)
            {
                Console.WriteLine("Skip applying summary!");
                return;
            }

            //Console.WriteLine($"{indent}{summary.Signature} APPLYING...");
            result.Stat.StartSummaryApplying(summary.Signature.ToString());

            // Match
            var context = new SymbolicReference.ApplyingContext(CallStack);

            Static.Match(context, summary.Static);
            for (int i = 0; i < parameters.Length; i++)
            {
                parameters[i].Match(context, summary.Arguments[i]);
            }

            // Apply
            if (enableStaticFields)
            {
                staticEntity.Apply(context, summary.Static, result);
            }

            for (int i = 0; i < parameters.Length; i++)
            {
                parameters[i].Apply(context, summary.Arguments[i], result);
            }

            if (summary.ReturnValue != null)
            {
                var matchedReturnValue = new SymbolicSlot(summary.ReturnValue.GetMatchedValue(context, result));
                switch (returnValueApplying)
                {
                case ReturnValueApplyingMode.Replace:
                    Frame.Pop();
                    Frame.Push(matchedReturnValue);
                    break;

                case ReturnValueApplyingMode.Merge:
                    var returnedSlot = Frame.Pop();
                    Frame.Push(SymbolicSlot.Merge(returnedSlot, matchedReturnValue));
                    break;

                default:
                    throw new NotSupportedException();
                }
            }

            //Console.WriteLine($"Apply({summary.OutScopeMap.Count}): {timer.ElapsedMilliseconds} ms");

/*
 *          Debug.Assert(Static.entities.Length == 1);
 *          foreach (var f in Static.entities[0].fields)
 *          {
 *              if (f.Value.source is ArgumentSource arg)
 *              {
 *                  Debug.Assert(arg.signature == Signature);
 *              }
 *          }
 */

            result.Stat.StopSummaryApplying(method.CreateMethodUniqueSignature().ToString(), summary);
            result.Stat.AppliedSummaryCount++;
        }
 public CtorCallEffect(IMethod method,
                       SymbolicSlot[] symbolicParameters,
                       SymbolicSlot symbolicRetSlot)
     : base(method, symbolicParameters, symbolicRetSlot, CallKind.Concrete)
 {
 }