Beispiel #1
0
        public override CILInstruction Execute(mmchecker.vm.ThreadState threadState)
        {
            if(CanExecute(threadState) == false)
                throw new Exception("This instruction is not ready to start");

            if(theMethod.ParentClass.Name == "[mscorlib]System.Threading.Thread")
            {
                if(theMethod.Name == "Start")
                {
                    // Gets the needed details and then add the thread to global datastructure
                    // The new thread is ready to be executed in the next step
                    // TODO: Do POR on initial bytecodes of the thread to reduce one step
                    VMValue_object threadptr = (VMValue_object)threadState.GetValue(threadState.ThreadStack.Pop());
                    VMValue_thread threadobj = (VMValue_thread)threadState.GetValue(threadptr.ValueGUID);
                    ThreadState newThread = new ThreadState(threadState.SystemState, threadobj);
                    // no need to refer back
                    // TODO: we may need the details later, but it causes problems for dynamic escape analysis
                    // by letting the original thread keep the pointer to the object
                    threadobj.ThreadStartGUID = -1;

                    threadState.SystemState.AddThread(newThread);
                    return threadState.CurrentMethod.GetNextInstruction(this);
                }
                else if(theMethod.Name == "Join")
                {
                    // Only need to pop the thread id, because the CanExecute() already
                    // make sure the thread that this thread must join has already ended
                    threadState.ThreadStack.Pop();
                    return threadState.CurrentMethod.GetNextInstruction(this);
                }else
                    throw new Exception("Not supported yet");
            }
            else
            {
                return threadState.CallFunction(theMethod);
            }
        }
Beispiel #2
0
        public override CILInstruction Execute(mmchecker.vm.ThreadState threadState)
        {
            VMValue_double v, vnew, vpower, vbase;
            VMValue_int32 vint;

            if(CanExecute(threadState) == false)
                throw new Exception("Something's wrong, executing assertion when value is not ready");
            if(theMethod.ParentClass.Name == "[mscorlib]System.Object")
            {
                if(theMethod.Name == ".ctor")
                    return threadState.CurrentMethod.GetNextInstruction(this);
            }
            else if(theMethod.ParentClass.Name == "MMC")
            {
                // this is the checker's assertion class
                if(theMethod.Name == "Report")
                {
                    vint = (VMValue_int32)threadState.GetValue(threadState.ThreadStack.Pop());
                    threadState.SystemState.Report(vint.Value);
                }
                return threadState.CurrentMethod.GetNextInstruction(this);
            }
            else if(theMethod.ParentClass.Name == "[mscorlib]System.Threading.Thread")
            {
                // just go pass this instruction because the CanExecute() has made sure
                // that there is incomplete bytecodes
                if(theMethod.Name == "MemoryBarrier")
                    return threadState.CurrentMethod.GetNextInstruction(this);
                else
                    throw new Exception("Not supported function " + theMethod.ParentClass.Name + "::" + theMethod.Name);
            }
            else if(theMethod.ParentClass.Name == "[mscorlib]System.Threading.Monitor")
            {
                if(theMethod.Name == "Enter")
                {
                    VMValue_object obj = (VMValue_object)threadState.GetValue(threadState.ThreadStack.Pop());
                    DelayedLock dl = new DelayedLock(obj.ValueGUID, this);
                    threadState.AddPendingAction(dl);
                    return threadState.CurrentMethod.GetNextInstruction(this);
                }
                else if(theMethod.Name == "Exit")
                {
                    VMValue_object obj = (VMValue_object)threadState.GetValue(threadState.ThreadStack.Pop());
                    DelayedUnlock du = new DelayedUnlock(obj.ValueGUID, this);
                    threadState.AddPendingAction(du);
                    return threadState.CurrentMethod.GetNextInstruction(this);
                }
                else if(theMethod.Name == "Wait")
                {
                    VMValue_object obj = (VMValue_object)threadState.GetValue(threadState.ThreadStack.Pop());
                    DelayedWait du = new DelayedWait(obj.ValueGUID, this, 0);
                    threadState.AddPendingAction(du);

                    // set this thread to waiting
                    threadState.syncState = ThreadState.SyncState.WAITING;
                    threadState.waitingOn = obj.ValueGUID;

                    // release the lock
                    VMValue_objectinst objinst = (VMValue_objectinst)threadState.GetValue(obj.ValueGUID);
                    du.lockCount = objinst.HoldingLockCount;
                    objinst.HoldingLockCount = 0;
                    objinst.HoldingLockThreadID = -1;

                    // TODO: Now wait always return 1, change to reflect the result of the call
                    VMValue_int32 theConstant = (VMValue_int32)threadState.SystemState.Values.MakeValue(new CILVar_int32(""));
                    theConstant.Value = 1;
                    theConstant.IsThreadLocal = true;
                    theConstant.IsConcrete = true;
                    threadState.ThreadStack.Push(theConstant.GUID);

                    return threadState.CurrentMethod.GetNextInstruction(this);
                }
                else if(theMethod.Name == "Pulse")
                {
                    VMValue_object obj = (VMValue_object)threadState.GetValue(threadState.ThreadStack.Pop());
                    DelayedPulse du = new DelayedPulse(obj.ValueGUID, this, false);
                    threadState.AddPendingAction(du);
                    return threadState.CurrentMethod.GetNextInstruction(this);
                }
                else if(theMethod.Name == "PulseAll")
                {
                    VMValue_object obj = (VMValue_object)threadState.GetValue(threadState.ThreadStack.Pop());
                    DelayedPulse du = new DelayedPulse(obj.ValueGUID, this, true);
                    threadState.AddPendingAction(du);
                    return threadState.CurrentMethod.GetNextInstruction(this);
                }else
                    throw new Exception("Function " + theMethod.Name + " of class Monitor is not supported");
            }
            else if(theMethod.ParentClass.Name == "[mscorlib]System.Math")
            {
                // arithmetic instructions, just do the mathematics associated with each
                switch(theMethod.Name)
                {
                    case "Abs":
                        v = (VMValue_double)threadState.GetValue(threadState.ThreadStack.Pop());
                        vnew = (VMValue_double)threadState.SystemState.Values.MakeValue(v);
                        vnew.IsThreadLocal = true;
                        vnew.IsConcrete = true;
                        vnew.Value = Math.Abs(v.Value);
                        threadState.ThreadStack.Push(vnew.GUID);
                        break;
                    case "Sin":
                        v = (VMValue_double)threadState.GetValue(threadState.ThreadStack.Pop());
                        vnew = (VMValue_double)threadState.SystemState.Values.MakeValue(v);
                        vnew.IsThreadLocal = true;
                        vnew.IsConcrete = true;
                        vnew.Value = Math.Sin(v.Value);
                        threadState.ThreadStack.Push(vnew.GUID);
                        break;
                    case "Cos":
                        v = (VMValue_double)threadState.GetValue(threadState.ThreadStack.Pop());
                        vnew = (VMValue_double)threadState.SystemState.Values.MakeValue(v);
                        vnew.IsThreadLocal = true;
                        vnew.IsConcrete = true;
                        vnew.Value = Math.Cos(v.Value);
                        threadState.ThreadStack.Push(vnew.GUID);
                        break;
                    case "Pow":
                        vpower = (VMValue_double)threadState.GetValue(threadState.ThreadStack.Pop());
                        vbase = (VMValue_double)threadState.GetValue(threadState.ThreadStack.Pop());
                        vnew = (VMValue_double)threadState.SystemState.Values.MakeValue(vpower);
                        vnew.IsThreadLocal = true;
                        vnew.IsConcrete = true;
                        vnew.Value = Math.Pow(vbase.Value, vpower.Value);
                        threadState.ThreadStack.Push(vnew.GUID);
                        break;
                    default:
                        throw new Exception("Not supported function of [mscorlib]System.Math");
                }
                return threadState.CurrentMethod.GetNextInstruction(this);
            }
            return threadState.CallFunction(theMethod);
        }