Exemple #1
0
        internal FindLocalVarState Copy()
        {
            FindLocalVarState copy = new FindLocalVarState();

            copy.sites = sites;
            return(copy);
        }
Exemple #2
0
 internal void Merge(FindLocalVarState state)
 {
     if (sites == null)
     {
         sites   = state.sites;
         changed = true;
     }
     else
     {
         bool dirty = true;
         for (int i = 0; i < sites.Length; i++)
         {
             for (int j = 0; j < state.sites[i].Count; j++)
             {
                 if (!sites[i].Contains(state.sites[i][j]))
                 {
                     if (dirty)
                     {
                         dirty = false;
                         sites = (FindLocalVarStoreSite[])sites.Clone();
                     }
                     sites[i].Add(state.sites[i][j]);
                     changed = true;
                 }
             }
         }
     }
 }
Exemple #3
0
    private static Dictionary <int, string>[] FindLocalVariables(CodeInfo codeInfo, MethodWrapper mw, ClassFile classFile, ClassFile.Method method)
    {
        FindLocalVarState[] state = new FindLocalVarState[method.Instructions.Length];
        state[0].changed = true;
        state[0].sites   = new FindLocalVarStoreSite[method.MaxLocals];
        TypeWrapper[] parameters = mw.GetParameters();
        int           argpos     = 0;

        if (!mw.IsStatic)
        {
            state[0].sites[argpos++].Add(-1);
        }
        for (int i = 0; i < parameters.Length; i++)
        {
            state[0].sites[argpos++].Add(-1);
            if (parameters[i].IsWidePrimitive)
            {
                argpos++;
            }
        }
        return(FindLocalVariablesImpl(codeInfo, classFile, method, state));
    }
Exemple #4
0
    private static Dictionary <int, string>[] FindLocalVariablesImpl(CodeInfo codeInfo, ClassFile classFile, ClassFile.Method method, FindLocalVarState[] state)
    {
        ClassFile.Method.Instruction[] instructions = method.Instructions;
        ExceptionTableEntry[]          exceptions   = method.ExceptionTable;
        int maxLocals = method.MaxLocals;

        Dictionary <int, string>[] localStoreReaders = new Dictionary <int, string> [instructions.Length];
        bool done = false;

        while (!done)
        {
            done = true;
            for (int i = 0; i < instructions.Length; i++)
            {
                if (state[i].changed)
                {
                    done             = false;
                    state[i].changed = false;

                    FindLocalVarState curr = state[i].Copy();

                    for (int j = 0; j < exceptions.Length; j++)
                    {
                        if (exceptions[j].startIndex <= i && i < exceptions[j].endIndex)
                        {
                            state[exceptions[j].handlerIndex].Merge(curr);
                        }
                    }

                    if (IsLoadLocal(instructions[i].NormalizedOpCode) &&
                        (instructions[i].NormalizedOpCode != NormalizedByteCode.__aload || !VerifierTypeWrapper.IsFaultBlockException(codeInfo.GetRawStackTypeWrapper(i + 1, 0))))
                    {
                        if (localStoreReaders[i] == null)
                        {
                            localStoreReaders[i] = new Dictionary <int, string>();
                        }
                        for (int j = 0; j < curr.sites[instructions[i].NormalizedArg1].Count; j++)
                        {
                            localStoreReaders[i][curr.sites[instructions[i].NormalizedArg1][j]] = "";
                        }
                    }

                    if (IsStoreLocal(instructions[i].NormalizedOpCode) &&
                        (instructions[i].NormalizedOpCode != NormalizedByteCode.__astore || !VerifierTypeWrapper.IsFaultBlockException(codeInfo.GetRawStackTypeWrapper(i, 0))))
                    {
                        curr.Store(i, instructions[i].NormalizedArg1);
                        // if this is a store at the end of an exception block,
                        // we need to propagate the new state to the exception handler
                        for (int j = 0; j < exceptions.Length; j++)
                        {
                            if (exceptions[j].endIndex == i + 1)
                            {
                                state[exceptions[j].handlerIndex].Merge(curr);
                            }
                        }
                    }

                    if (instructions[i].NormalizedOpCode == NormalizedByteCode.__invokespecial)
                    {
                        ClassFile.ConstantPoolItemMI cpi = classFile.GetMethodref(instructions[i].Arg1);
                        if (ReferenceEquals(cpi.Name, StringConstants.INIT))
                        {
                            TypeWrapper type = codeInfo.GetRawStackTypeWrapper(i, cpi.GetArgTypes().Length);
                            // after we've invoked the constructor, the uninitialized references
                            // are now initialized
                            if (type == VerifierTypeWrapper.UninitializedThis ||
                                VerifierTypeWrapper.IsNew(type))
                            {
                                for (int j = 0; j < maxLocals; j++)
                                {
                                    if (codeInfo.GetLocalTypeWrapper(i, j) == type)
                                    {
                                        curr.Store(i, j);
                                    }
                                }
                            }
                        }
                    }
                    else if (instructions[i].NormalizedOpCode == NormalizedByteCode.__goto_finally)
                    {
                        int handler = instructions[i].HandlerIndex;

                        // Normally a store at the end of a try block doesn't affect the handler block,
                        // but in the case of a finally handler it does, so we need to make sure that
                        // we merge here in case the try block ended with a store.
                        state[handler].Merge(curr);

                        // Now we recursively analyse the handler and afterwards merge the endfault locations back to us
                        FindLocalVarState[] handlerState = new FindLocalVarState[instructions.Length];
                        handlerState[handler].Merge(curr);
                        curr = new FindLocalVarState();
                        FindLocalVariablesImpl(codeInfo, classFile, method, handlerState);

                        // Merge back to the target of our __goto_finally
                        for (int j = 0; j < handlerState.Length; j++)
                        {
                            if (instructions[j].NormalizedOpCode == NormalizedByteCode.__athrow &&
                                codeInfo.HasState(j) &&
                                VerifierTypeWrapper.IsFaultBlockException(codeInfo.GetRawStackTypeWrapper(j, 0)) &&
                                ((VerifierTypeWrapper)codeInfo.GetRawStackTypeWrapper(j, 0)).Index == handler)
                            {
                                curr.Merge(handlerState[j]);
                            }
                        }
                    }

                    switch (ByteCodeMetaData.GetFlowControl(instructions[i].NormalizedOpCode))
                    {
                    case ByteCodeFlowControl.Switch:
                    {
                        for (int j = 0; j < instructions[i].SwitchEntryCount; j++)
                        {
                            state[instructions[i].GetSwitchTargetIndex(j)].Merge(curr);
                        }
                        state[instructions[i].DefaultTarget].Merge(curr);
                        break;
                    }

                    case ByteCodeFlowControl.Branch:
                        state[instructions[i].TargetIndex].Merge(curr);
                        break;

                    case ByteCodeFlowControl.CondBranch:
                        state[instructions[i].TargetIndex].Merge(curr);
                        state[i + 1].Merge(curr);
                        break;

                    case ByteCodeFlowControl.Return:
                    case ByteCodeFlowControl.Throw:
                        break;

                    case ByteCodeFlowControl.Next:
                        state[i + 1].Merge(curr);
                        break;

                    default:
                        throw new InvalidOperationException();
                    }
                }
            }
        }
        return(localStoreReaders);
    }
Exemple #5
0
	private static Dictionary<int, string>[] FindLocalVariablesImpl(CodeInfo codeInfo, ClassFile classFile, ClassFile.Method method, FindLocalVarState[] state)
	{
		ClassFile.Method.Instruction[] instructions = method.Instructions;
		ExceptionTableEntry[] exceptions = method.ExceptionTable;
		int maxLocals = method.MaxLocals;
		Dictionary<int, string>[] localStoreReaders = new Dictionary<int, string>[instructions.Length];
		bool done = false;

		while (!done)
		{
			done = true;
			for (int i = 0; i < instructions.Length; i++)
			{
				if (state[i].changed)
				{
					done = false;
					state[i].changed = false;

					FindLocalVarState curr = state[i].Copy();

					for (int j = 0; j < exceptions.Length; j++)
					{
						if (exceptions[j].startIndex <= i && i < exceptions[j].endIndex)
						{
							state[exceptions[j].handlerIndex].Merge(curr);
						}
					}

					if (IsLoadLocal(instructions[i].NormalizedOpCode)
						&& (instructions[i].NormalizedOpCode != NormalizedByteCode.__aload || !VerifierTypeWrapper.IsFaultBlockException(codeInfo.GetRawStackTypeWrapper(i + 1, 0))))
					{
						if (localStoreReaders[i] == null)
						{
							localStoreReaders[i] = new Dictionary<int, string>();
						}
						for (int j = 0; j < curr.sites[instructions[i].NormalizedArg1].Count; j++)
						{
							localStoreReaders[i][curr.sites[instructions[i].NormalizedArg1][j]] = "";
						}
					}

					if (IsStoreLocal(instructions[i].NormalizedOpCode)
						&& (instructions[i].NormalizedOpCode != NormalizedByteCode.__astore || !VerifierTypeWrapper.IsFaultBlockException(codeInfo.GetRawStackTypeWrapper(i, 0))))
					{
						curr.Store(i, instructions[i].NormalizedArg1);
						// if this is a store at the end of an exception block,
						// we need to propagate the new state to the exception handler
						for (int j = 0; j < exceptions.Length; j++)
						{
							if (exceptions[j].endIndex == i + 1)
							{
								state[exceptions[j].handlerIndex].Merge(curr);
							}
						}
					}

					if (instructions[i].NormalizedOpCode == NormalizedByteCode.__invokespecial)
					{
						ClassFile.ConstantPoolItemMI cpi = classFile.GetMethodref(instructions[i].Arg1);
						if (ReferenceEquals(cpi.Name, StringConstants.INIT))
						{
							TypeWrapper type = codeInfo.GetRawStackTypeWrapper(i, cpi.GetArgTypes().Length);
							// after we've invoked the constructor, the uninitialized references
							// are now initialized
							if (type == VerifierTypeWrapper.UninitializedThis
								|| VerifierTypeWrapper.IsNew(type))
							{
								for (int j = 0; j < maxLocals; j++)
								{
									if (codeInfo.GetLocalTypeWrapper(i, j) == type)
									{
										curr.Store(i, j);
									}
								}
							}
						}
					}
					else if (instructions[i].NormalizedOpCode == NormalizedByteCode.__goto_finally)
					{
						int handler = instructions[i].HandlerIndex;

						// Normally a store at the end of a try block doesn't affect the handler block,
						// but in the case of a finally handler it does, so we need to make sure that
						// we merge here in case the try block ended with a store.
						state[handler].Merge(curr);

						// Now we recursively analyse the handler and afterwards merge the endfault locations back to us
						FindLocalVarState[] handlerState = new FindLocalVarState[instructions.Length];
						handlerState[handler].Merge(curr);
						curr = new FindLocalVarState();
						FindLocalVariablesImpl(codeInfo, classFile, method, handlerState);

						// Merge back to the target of our __goto_finally
						for (int j = 0; j < handlerState.Length; j++)
						{
							if (instructions[j].NormalizedOpCode == NormalizedByteCode.__athrow
								&& codeInfo.HasState(j)
								&& VerifierTypeWrapper.IsFaultBlockException(codeInfo.GetRawStackTypeWrapper(j, 0))
								&& ((VerifierTypeWrapper)codeInfo.GetRawStackTypeWrapper(j, 0)).Index == handler)
							{
								curr.Merge(handlerState[j]);
							}
						}
					}

					switch (ByteCodeMetaData.GetFlowControl(instructions[i].NormalizedOpCode))
					{
						case ByteCodeFlowControl.Switch:
							{
								for (int j = 0; j < instructions[i].SwitchEntryCount; j++)
								{
									state[instructions[i].GetSwitchTargetIndex(j)].Merge(curr);
								}
								state[instructions[i].DefaultTarget].Merge(curr);
								break;
							}
						case ByteCodeFlowControl.Branch:
							state[instructions[i].TargetIndex].Merge(curr);
							break;
						case ByteCodeFlowControl.CondBranch:
							state[instructions[i].TargetIndex].Merge(curr);
							state[i + 1].Merge(curr);
							break;
						case ByteCodeFlowControl.Return:
						case ByteCodeFlowControl.Throw:
							break;
						case ByteCodeFlowControl.Next:
							state[i + 1].Merge(curr);
							break;
						default:
							throw new InvalidOperationException();
					}
				}
			}
		}
		return localStoreReaders;
	}
Exemple #6
0
	private static Dictionary<int, string>[] FindLocalVariables(CodeInfo codeInfo, MethodWrapper mw, ClassFile classFile, ClassFile.Method method)
	{
		FindLocalVarState[] state = new FindLocalVarState[method.Instructions.Length];
		state[0].changed = true;
		state[0].sites = new FindLocalVarStoreSite[method.MaxLocals];
		TypeWrapper[] parameters = mw.GetParameters();
		int argpos = 0;
		if (!mw.IsStatic)
		{
			state[0].sites[argpos++].Add(-1);
		}
		for (int i = 0; i < parameters.Length; i++)
		{
			state[0].sites[argpos++].Add(-1);
			if (parameters[i].IsWidePrimitive)
			{
				argpos++;
			}
		}
		return FindLocalVariablesImpl(codeInfo, classFile, method, state);
	}
Exemple #7
0
		internal FindLocalVarState Copy()
		{
			FindLocalVarState copy = new FindLocalVarState();
			copy.sites = sites;
			return copy;
		}
Exemple #8
0
		internal void Merge(FindLocalVarState state)
		{
			if (sites == null)
			{
				sites = state.sites;
				changed = true;
			}
			else
			{
				bool dirty = true;
				for (int i = 0; i < sites.Length; i++)
				{
					for (int j = 0; j < state.sites[i].Count; j++)
					{
						if (!sites[i].Contains(state.sites[i][j]))
						{
							if (dirty)
							{
								dirty = false;
								sites = (FindLocalVarStoreSite[])sites.Clone();
							}
							sites[i].Add(state.sites[i][j]);
							changed = true;
						}
					}
				}
			}
		}