Example #1
0
        public static IType GetInstType(ILInstruction inst, IType typeHint = null)
        {
            if (inst.MatchCastClass(out ILInstruction arg, out IType type))
            {
                return(type);
            }

            var call = inst as CallInstruction;

            if (call != null)
            {
                return(call.Method.ReturnType);
            }

            if (inst.MatchLdLoc(out ILVariable var))
            {
                return(GetVariableType(var));
            }

            if (inst.MatchLdNull())
            {
                return(null);
            }

            if (inst.MatchLdStr(out string xx))
            {
                // we don't handle string literals. Should be replaced finally
                return(null);
            }

            if (inst.MatchLdObj(out var target, out var fldType))
            {
                if (target.MatchLdsFlda(out var sfield))
                {
                    return(sfield.Type);
                }

                if (target.MatchLdFlda(out var target2, out var field))
                {
                    return(field.Type);
                }
            }
            if (inst.MatchLdLoca(out var v))
            {
                return(new PointerType(v.Type));
            }

            if (inst.MatchLdFlda(out var target3, out var field2))
            {
                return(new PointerType(field2.Type));
            }

            if (inst.MatchLdsFlda(out var field4))
            {
                return(new PointerType(field4.Type));
            }

            if (inst.MatchLdObj(out var target4, out var type3))
            {
                return(type3);
            }


            if (inst.MatchLdTypeToken(out var type4))
            {
                return(null);
            }

            if (inst is Conv c)
            {
                // todo handle integer types
                return(null);
            }
            // todo field, etc
            Debug.Assert(false, "Implement this type: " + inst.GetType().Name);
            return(null);
        }
        protected sealed override void Default(ILInstruction inst)
        {
            DebugStartPoint(inst);
            // This method assumes normal control flow and no branches.
            if ((inst.DirectFlags & flagsRequiringManualImpl) != 0)
            {
                throw new NotImplementedException(GetType().Name + " is missing implementation for " + inst.GetType().Name);
            }

            // Since this instruction has normal control flow, we can evaluate our children left-to-right.
            foreach (var child in inst.Children)
            {
                child.AcceptVisitor(this);
                Debug.Assert(state.IsBottom || !child.HasFlag(InstructionFlags.EndPointUnreachable),
                             "Unreachable code must be in the bottom state.");
            }

            DebugEndPoint(inst);
        }
Example #3
0
        public void Interpret(AppDomain appDomain, ILMethodDefinition method, params object[] arguments)
        {
            object[] locals = new object[20];

            for (int i = 0; i < method.Instructions.Length; i++)
            {
                ILInstruction instruction = method.Instructions[i];

                switch (instruction)
                {
                case NopInstruction nop:
                    break;
                //case CallInstruction call:
                //	ILMethodDefinition callMethod = appDomain.Loader.ReadMethod(call.Target);

                //	object[] args = new object[callMethod.ArgumentsCount];
                //	for (int j = 0; j < args.Length; j++)
                //	{
                //		args[j] = this.Stack.Dequeue();
                //	}

                //	this.Interpret(appDomain, callMethod, args);

                //	break;
                case PushInt32Instruction push:
                    this.Stack.Enqueue(push.Value);
                    break;

                case PushInt64Instruction push:
                    this.Stack.Enqueue(push.Value);
                    break;

                case StoreLocalInstruction store:
                    locals[store.Index] = this.Stack.Dequeue();
                    break;

                case BranchInstruction branch:
                    i = method.ILOffsets[branch.ToIndex] - 1;
                    break;

                case LoadLocalInstruction load:
                    this.Stack.Enqueue(locals[load.Index]);
                    break;

                case ReturnInstruction @return:
                    return;

                case LoadArgumentInstruction argument:
                    this.Stack.Enqueue(arguments[argument.Index]);
                    break;

                case BranchFalseInstruction branch:
                    object value = this.Stack.Dequeue();
                    if (value is int number && number == 0)
                    {
                        i = method.ILOffsets[branch.ToIndex] - 1;
                    }
                    break;

                case AddInstruction add:
                {
                    int num  = (int)this.Stack.Dequeue();
                    int num2 = (int)this.Stack.Dequeue();

                    this.Stack.Enqueue(num + num2);
                    break;
                }

                case SubtractInstruction sub:
                {
                    int num  = (int)this.Stack.Dequeue();
                    int num2 = (int)this.Stack.Dequeue();

                    this.Stack.Enqueue(num - num2);
                    break;
                }

                case BranchGreaterInstruction greater:
                {
                    break;
                }

                default:
                    throw new InvalidOperationException("Wtf is tihs: " + instruction.GetType());
                }
            }

            throw new InvalidOperationException("not like tihs");
        }