コード例 #1
0
ファイル: Conv_Multi.cs プロジェクト: leebing/AntShares.VM
        public bool IsOpCall(Mono.Cecil.MethodReference refs, out string name)
        {
            var defs = refs.Resolve();

            foreach (var attr in defs.CustomAttributes)
            {
                if (attr.AttributeType.Name == "ScriptOpAttribute")
                {
                    var type  = attr.ConstructorArguments[0].Type;
                    var value = (byte)attr.ConstructorArguments[0].Value;

                    foreach (var t in type.Resolve().Fields)
                    {
                        if (t.Constant != null)
                        {
                            if ((byte)t.Constant == value)
                            {
                                //dosth
                                name = t.Name;
                                return(true);
                            }
                        }
                    }
                }
                //if(attr.t)
            }
            name = "";
            return(false);
        }
コード例 #2
0
        public bool IsAppCall(Mono.Cecil.MethodReference refs, out byte[] hash)
        {
            try
            {
                var defs = refs.Resolve();
                foreach (var attr in defs.CustomAttributes)
                {
                    if (attr.AttributeType.Name == "AppcallAttribute")
                    {
                        var type = attr.ConstructorArguments[0].Type;
                        var a    = attr.ConstructorArguments[0];
                        var list = a.Value as Mono.Cecil.CustomAttributeArgument[];
                        hash = new byte[20];
                        for (var i = 0; i < 20; i++)
                        {
                            hash[i] = (byte)list[i].Value;
                        }

                        //dosth
                        return(true);
                    }
                    //if(attr.t)
                }
                hash = null;
                return(false);
            }
            catch
            {
                hash = null;
                return(false);
            }
        }
コード例 #3
0
        IMethod GetMethod(object token)
        {
            Mono.Cecil.ModuleDefinition module = null;
            string          methodname         = null;
            string          typename           = null;
            MethodParamList genlist            = null;
            MethodParamList list = null;

            if (token is Mono.Cecil.MethodReference)
            {
                Mono.Cecil.MethodReference _ref = (token as Mono.Cecil.MethodReference);
                module     = _ref.Module;
                methodname = _ref.Name;
                typename   = _ref.DeclaringType.FullName;
                list       = new MethodParamList(environment, _ref);
                if (_ref.IsGenericInstance)
                {
                    Mono.Cecil.GenericInstanceMethod gmethod = _ref as Mono.Cecil.GenericInstanceMethod;
                    genlist = new MethodParamList(environment, gmethod);
                }
            }
            else if (token is Mono.Cecil.MethodDefinition)
            {
                Mono.Cecil.MethodDefinition _def = token as Mono.Cecil.MethodDefinition;
                module     = _def.Module;
                methodname = _def.Name;
                typename   = _def.DeclaringType.FullName;
                list       = new MethodParamList(environment, _def);
                if (_def.IsGenericInstance)
                {
                    throw new NotImplementedException();
                    //Mono.Cecil.GenericInstanceMethod gmethod = _def as Mono.Cecil.GenericInstanceMethod;
                    //genlist = new MethodParamList(environment, gmethod);
                }
            }
            else
            {
                throw new NotImplementedException();
            }
            var typesys = GetType(typename, module);

            if (typesys == null)
            {
                throw new Exception("type can't find:" + typename);
            }


            IMethod _method = null;

            if (genlist != null)
            {
                _method = typesys.GetMethodT(methodname, genlist, list);
            }
            else
            {
                _method = typesys.GetMethod(methodname, list);
            }

            return(_method);
        }
コード例 #4
0
        public bool IsSysCall(Mono.Cecil.MethodReference refs, out string name)
        {
            try
            {
                var defs = refs.Resolve();
                foreach (var attr in defs.CustomAttributes)
                {
                    if (attr.AttributeType.Name == "SyscallAttribute")
                    {
                        var type  = attr.ConstructorArguments[0].Type;
                        var value = (string)attr.ConstructorArguments[0].Value;

                        //dosth
                        name = value;
                        return(true);
                    }
                    //if(attr.t)
                }
                name = "";
                return(false);
            }
            catch
            {
                name = "";
                return(false);
            }
        }
コード例 #5
0
ファイル: TypeHelpers.cs プロジェクト: deepankarsharma/Flame
        private static Mono.Cecil.MethodReference CloneMethodWithDeclaringType(
            Mono.Cecil.MethodReference methodDef,
            Mono.Cecil.TypeReference declaringTypeRef)
        {
            if (!declaringTypeRef.IsGenericInstance || methodDef == null)
            {
                return(methodDef);
            }

            var methodRef = new Mono.Cecil.MethodReference(methodDef.Name, methodDef.ReturnType, declaringTypeRef)
            {
                CallingConvention = methodDef.CallingConvention,
                HasThis           = methodDef.HasThis,
                ExplicitThis      = methodDef.ExplicitThis
            };

            foreach (Mono.Cecil.GenericParameter genParamDef in methodDef.GenericParameters)
            {
                methodRef.GenericParameters.Add(CloneGenericParameter(genParamDef, methodRef));
            }

            methodRef.ReturnType = declaringTypeRef.Module.ImportReference(methodDef.ReturnType, methodRef);

            foreach (Mono.Cecil.ParameterDefinition paramDef in methodDef.Parameters)
            {
                methodRef.Parameters.Add(
                    new Mono.Cecil.ParameterDefinition(
                        paramDef.Name, paramDef.Attributes,
                        declaringTypeRef.Module.ImportReference(paramDef.ParameterType, methodRef)));
            }

            return(methodRef);
        }
コード例 #6
0
 public static void InjectPrologue(Mono.Cecil.MethodReference methodRef)
 {
     if (null != s_CurFile)
     {
         s_CurFile.InjectPrologue(methodRef);
     }
 }
コード例 #7
0
ファイル: Type_List.cs プロジェクト: zhangf911/LSharp
        public MethodParamList(ICLRSharp_Environment env, Mono.Cecil.MethodReference method)
        {
            if (method.HasParameters)
            {
                Mono.Cecil.GenericInstanceType _typegen = null;
                _typegen = method.DeclaringType as Mono.Cecil.GenericInstanceType;
                Mono.Cecil.GenericInstanceMethod gm = method as Mono.Cecil.GenericInstanceMethod;
                MethodParamList _methodgen          = null;
                if (gm != null)
                {
                    _methodgen = new MethodParamList(env, gm);
                }
                foreach (var p in method.Parameters)
                {
                    string paramname = p.ParameterType.FullName;

                    if (p.ParameterType.IsGenericParameter)
                    {
                        if (p.ParameterType.Name.Contains("!!"))
                        {
                            int index = int.Parse(p.ParameterType.Name.Substring(2));
                            paramname = _methodgen[index].FullName;
                        }
                        else if (p.ParameterType.Name.Contains("!"))
                        {
                            int index = int.Parse(p.ParameterType.Name.Substring(1));
                            paramname = _typegen.GenericArguments[index].FullName;
                        }
                    }

                    if (paramname.Contains("!!"))
                    {
                        //string typename = param.ParameterType.FullName;
                        for (int i = 0; i < _methodgen.Count; i++)
                        {
                            string pp = "!!" + i.ToString();
                            paramname = paramname.Replace(pp, _methodgen[i].FullName);
                        }
                        //this.Add(GetTType(env, p, _methodgen));
                    }

                    if (paramname.Contains("!"))//函数有T
                    {
                        var gens = (method.DeclaringType as Mono.Cecil.GenericInstanceType).GenericArguments;
                        for (int i = 0; i < gens.Count; i++)
                        {
                            string pp = "!" + i.ToString();
                            paramname = paramname.Replace(pp, gens[i].FullName);
                        }
                    }
                    //else
                    {
                        this.Add(env.GetType(paramname));
                    }
                }
            }
        }
コード例 #8
0
        public IMethod Resolve(Mono.Cecil.MethodReference methodReference)
        {
            IMethod method = context.Resolve(methodReference);

            if (method != null)
            {
                method = (IMethod)method.Specialize(substitution);
            }
            return(method);
        }
コード例 #9
0
        public static bool CheckMethod(Mono.Cecil.MethodDefinition methodDef, Mono.Cecil.MethodReference methodRef)
        {
            string func;

            if (s_CheckMethodFuncs.TryGetValue(methodRef.Name, out func))
            {
                var ret = s_Calculator.Calc(func, methodDef, methodRef);
                if (null != ret)
                {
                    return((bool)Convert.ChangeType(ret, typeof(bool)));
                }
            }
            return(true);
        }
コード例 #10
0
 private static void ConvertMethodDefinition(MethodReference method, TypeReference enumType)
 {
     if (method.ReturnType.FullName == SystemEnumName)
     {
         method.ReturnType = enumType;
     }
     foreach (var p in method.Parameters)
     {
         if (p.ParameterType.FullName == SystemEnumName)
         {
             p.ParameterType = enumType;
         }
     }
 }
コード例 #11
0
ファイル: Conv_Multi.cs プロジェクト: leebing/AntShares.VM
        private int _ConvertCall(OpCode src, AntsMethod to)
        {
            Mono.Cecil.MethodReference refs = src.tokenUnknown as Mono.Cecil.MethodReference;

            if (this.outModule.mapMethods.ContainsKey(src.tokenMethod))
            {//this is a call
                var c = _Convert1by1(AntShares.VM.OpCode.CALL, src, to, new byte[] { 5, 0 });
                c.needfix = true;
                c.srcfunc = src.tokenMethod;
                return(0);
            }
            else if (refs.ReturnType.Name == "ScriptEngine")
            {
                //donothing 語法過渡類型
                return(0);
            }
            else
            {//maybe a syscall // or other
                if (src.tokenMethod == "System.Int32 System.Numerics.BigInteger::op_Explicit(System.Numerics.BigInteger)")
                {
                    //donothing
                    return(0);
                }
                else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Implicit(System.Int32)")//int->bignumber
                {
                    //donothing
                    return(0);
                }
                else
                {
                    string name;
                    if (IsOpCall(refs, out name))
                    {
                        if (name == "CHECKSIG")
                        {
                            _Convert1by1(AntShares.VM.OpCode.CHECKSIG, src, to);
                            return(0);
                        }
                    }
                    if (IsSysCall(refs, out name))
                    {
                        _Convert1by1(AntShares.VM.OpCode.SYSCALL, src, to, str2Pushdata1bytes(name));
                        return(0);
                    }
                    throw new Exception("unknown call:" + src.tokenMethod);
                }
            }
        }
コード例 #12
0
 public static ProductException CreateError(int code, Mono.Cecil.MemberReference member, string message, params object[] args)
 {
     Mono.Cecil.MethodReference method = member as Mono.Cecil.MethodReference;
     if (method == null)
     {
         var property = member as Mono.Cecil.PropertyDefinition;
         if (property != null)
         {
             method = property.GetMethod;
             if (method == null)
             {
                 method = property.SetMethod;
             }
         }
     }
     return(CreateError(code, method == null ? null : method.Resolve(), message, args));
 }
コード例 #13
0
ファイル: ErrorHelper.cs プロジェクト: ye-man/xamarin-macios
 public static ProductException Create(Application app, int code, bool error, Exception innerException, Mono.Cecil.MemberReference member, Instruction instruction, string message, params object [] args)
 {
     Mono.Cecil.MethodReference method = member as Mono.Cecil.MethodReference;
     if (method == null)
     {
         var property = member as Mono.Cecil.PropertyDefinition;
         if (property != null)
         {
             method = property.GetMethod;
             if (method == null)
             {
                 method = property.SetMethod;
             }
         }
     }
     return(Create(app, code, error, innerException, method == null ? null : method.Resolve(), instruction, message, args));
 }
コード例 #14
0
        public bool IsNotifyCall(Mono.Cecil.MethodDefinition defs, Mono.Cecil.MethodReference refs, NeoMethod to, out string name)
        {
            name = to.lastsfieldname;
            if (to.lastsfieldname == null)
            {
                return(false);
            }

            Mono.Cecil.TypeDefinition call = null;
            if (defs == null)
            {
                try
                {
                    call = refs.DeclaringType.Resolve();
                }
                catch
                {//当不能取得这个,大半都是模板类
                }
            }
            else
            {
                call = defs.DeclaringType;
            }

            if (call != null)
            {
                if (call.BaseType.Name == "MulticastDelegate" || call.BaseType.Name == "Delegate")
                {
                    to.lastsfieldname = null;
                    return(true);
                }
            }
            else//不能还原类型,只好用名字判断了
            {
                if (refs.Name == "Invoke" && refs.DeclaringType.Name.Contains("Action`"))
                {
                    to.lastsfieldname = null;
                    return(true);
                }
            }
            name = "Notify";
            return(false);
        }
コード例 #15
0
ファイル: Type_List.cs プロジェクト: sjb8100/LSharp
        public MethodParamList(ICLRSharp_Environment env, Mono.Cecil.MethodReference method)
        {
            if (method.HasParameters)
            {
                Mono.Cecil.GenericInstanceType _typegen = null;
                _typegen = method.DeclaringType as Mono.Cecil.GenericInstanceType;
                Mono.Cecil.GenericInstanceMethod gm = method as Mono.Cecil.GenericInstanceMethod;
                MethodParamList _methodgen          = null;
                if (gm != null)
                {
                    _methodgen = new MethodParamList(env, gm);
                }
                foreach (var p in method.Parameters)
                {
                    string paramname = p.ParameterType.FullName;

                    if (p.ParameterType.IsGenericParameter)
                    {
                        if (p.ParameterType.Name.Contains("!!"))
                        {
                            int index = int.Parse(p.ParameterType.Name.Substring(2));
                            paramname = _methodgen[index].FullName;
                        }
                        else if (p.ParameterType.Name.Contains("!"))
                        {
                            int index = int.Parse(p.ParameterType.Name.Substring(1));
                            paramname = _typegen.GenericArguments[index].FullName;
                        }
                    }

                    if (paramname.Contains("!!"))
                    {
                        this.Add(GetTType(env, p, method, _methodgen));
                    }
                    else
                    {
                        this.Add(env.GetType(paramname, method.Module));
                    }
                }
            }
        }
コード例 #16
0
ファイル: MethodEntry.cs プロジェクト: PlumpMath/ac3il
        public void ResetVirtualRegisters()
        {
            foreach (IR.InstructionElement i in this.FlatInstructionList)
            {
                switch (i.Instruction.OpCode.StackBehaviourPush)
                {
                case Mono.Cecil.Cil.StackBehaviour.Push0:
                    break;

                case Mono.Cecil.Cil.StackBehaviour.Varpush:
                    Mono.Cecil.MethodReference f = ((Mono.Cecil.MethodReference)i.Instruction.Operand);
                    if (f.ReturnType.ReturnType.FullName != "System.Void")
                    {
                        i.Register = new VirtualRegister();
                    }
                    break;

                case Mono.Cecil.Cil.StackBehaviour.Push1_push1:
                    i.Register    = new VirtualRegister();
                    i.DupRegister = new VirtualRegister();
                    break;

                case Mono.Cecil.Cil.StackBehaviour.Push1:
                case Mono.Cecil.Cil.StackBehaviour.Pushi:
                case Mono.Cecil.Cil.StackBehaviour.Pushi8:
                case Mono.Cecil.Cil.StackBehaviour.Pushr4:
                case Mono.Cecil.Cil.StackBehaviour.Pushr8:
                case Mono.Cecil.Cil.StackBehaviour.Pushref:
                    i.Register = new VirtualRegister();
                    break;

                default:
                    throw new Exception("Unexpected stack push type: " + i.Instruction.OpCode.StackBehaviourPush);
                }
            }
        }
コード例 #17
0
        private int _ConvertCall(OpCode src, NeoMethod to)
        {
            Mono.Cecil.MethodReference refs = src.tokenUnknown as Mono.Cecil.MethodReference;

            int    calltype   = 0;
            string callname   = "";
            int    callpcount = 0;

            byte[]    callhash = null;
            VM.OpCode callcode = VM.OpCode.NOP;

            Mono.Cecil.MethodDefinition defs = null;
            try
            {
                defs = refs.Resolve();
            }
            catch
            {
            }

            if (IsNonCall(defs))
            {
                return(0);
            }
            else if (IsNotifyCall(defs, refs, to, out callname))
            {
                calltype = 5;
            }
            else if (to.lastparam >= 0)
            {
                callpcount   = to.lastparam;
                calltype     = 6;
                to.lastparam = -1;
            }
            else if (IsOpCall(defs, out callname))
            {
                if (System.Enum.TryParse <VM.OpCode>(callname, out callcode))
                {
                    calltype = 2;
                }
                else
                {
                    throw new Exception("Can not find OpCall:" + callname);
                }
            }
            else if (IsSysCall(defs, out callname))
            {
                calltype = 3;
            }
            else if (IsAppCall(defs, out callhash))
            {
                calltype = 4;
            }
            else if (this.outModule.mapMethods.ContainsKey(src.tokenMethod))
            {//this is a call
                calltype = 1;
            }
            else
            {//maybe a syscall // or other
                if (src.tokenMethod.Contains("::op_Explicit(") || src.tokenMethod.Contains("::op_Implicit("))
                {
                    //各类显示隐示转换都忽略
                    //有可能有一些会特殊处理,故还保留独立判断
                    if (src.tokenMethod == "System.Int32 System.Numerics.BigInteger::op_Explicit(System.Numerics.BigInteger)")
                    {
                        //donothing
                        return(0);
                    }
                    else if (src.tokenMethod == "System.Int64 System.Numerics.BigInteger::op_Explicit(System.Numerics.BigInteger)")
                    {
                        //donothing
                        return(0);
                    }
                    else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Implicit(System.Int32)")//int->bignumber
                    {
                        //donothing
                        return(0);
                    }
                    else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Implicit(System.Int64)")
                    {
                        return(0);
                    }

                    return(0);
                }
                else if (src.tokenMethod == "System.Void System.Diagnostics.Debugger::Break()")
                {
                    _Convert1by1(VM.OpCode.NOP, src, to);

                    return(0);
                }
                else if (src.tokenMethod.Contains("::op_Equality(") || src.tokenMethod.Contains("::Equals("))
                {
                    var _ref = src.tokenUnknown as Mono.Cecil.MethodReference;

                    if (_ref.DeclaringType.FullName == "System.Boolean" ||
                        _ref.DeclaringType.FullName == "System.Int32" ||
                        _ref.DeclaringType.FullName == "System.Numerics.BigInteger")
                    {
                        _Convert1by1(VM.OpCode.NUMEQUAL, src, to);
                    }
                    else
                    {
                        _Convert1by1(VM.OpCode.EQUAL, src, to);
                    }
                    //各类==指令
                    //有可能有一些会特殊处理,故还保留独立判断
                    //if (src.tokenMethod == "System.Boolean System.String::op_Equality(System.String,System.String)")
                    //{
                    //    _Convert1by1(VM.OpCode.EQUAL, src, to);
                    //    return 0;
                    //}
                    //else if (src.tokenMethod == "System.Boolean System.Object::Equals(System.Object)")
                    //{
                    //    _Convert1by1(VM.OpCode.EQUAL, src, to);
                    //    return 0;
                    //}
                    //_Convert1by1(VM.OpCode.EQUAL, src, to);
                    return(0);
                }
                else if (src.tokenMethod.Contains("::op_Inequality("))
                {
                    var _ref = src.tokenUnknown as Mono.Cecil.MethodReference;
                    if (_ref.DeclaringType.FullName == "System.Boolean" ||
                        _ref.DeclaringType.FullName == "System.Int32" ||
                        _ref.DeclaringType.FullName == "System.Numerics.BigInteger")
                    {
                        _Convert1by1(VM.OpCode.NUMNOTEQUAL, src, to);
                    }
                    else
                    {
                        _Convert1by1(VM.OpCode.EQUAL, src, to);
                        _Convert1by1(VM.OpCode.NOT, null, to);
                    }
                    ////各类!=指令
                    ////有可能有一些会特殊处理,故还保留独立判断
                    //if (src.tokenMethod == "System.Boolean System.Numerics.BigInteger::op_Inequality(System.Numerics.BigInteger,System.Numerics.BigInteger)")
                    //{
                    //    _Convert1by1(VM.OpCode.INVERT, src, to);
                    //    _Insert1(VM.OpCode.EQUAL, "", to);
                    //    return 0;
                    //}
                    //_Convert1by1(VM.OpCode.INVERT, src, to);
                    //_Insert1(VM.OpCode.EQUAL, "", to);
                    return(0);
                }
                else if (src.tokenMethod.Contains("::op_Addition("))
                {
                    //各类+指令
                    //有可能有一些会特殊处理,故还保留独立判断
                    if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Addition(System.Numerics.BigInteger,System.Numerics.BigInteger)")
                    {
                        _Convert1by1(VM.OpCode.ADD, src, to);
                        return(0);
                    }
                    _Convert1by1(VM.OpCode.ADD, src, to);
                    return(0);
                }
                else if (src.tokenMethod.Contains("::op_Subtraction("))
                {
                    //各类-指令
                    //有可能有一些会特殊处理,故还保留独立判断
                    if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Subtraction(System.Numerics.BigInteger,System.Numerics.BigInteger)")
                    {
                        _Convert1by1(VM.OpCode.SUB, src, to);
                        return(0);
                    }
                    _Convert1by1(VM.OpCode.SUB, src, to);
                    return(0);
                }
                else if (src.tokenMethod.Contains("::op_Multiply("))
                {
                    //各类*指令
                    //有可能有一些会特殊处理,故还保留独立判断
                    if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Multiply(System.Numerics.BigInteger,System.Numerics.BigInteger)")
                    {
                        _Convert1by1(VM.OpCode.MUL, src, to);
                        return(0);
                    }
                    _Convert1by1(VM.OpCode.MUL, src, to);
                    return(0);
                }
                else if (src.tokenMethod.Contains("::op_Division("))
                {
                    //各类/指令
                    //有可能有一些会特殊处理,故还保留独立判断
                    if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Division(System.Numerics.BigInteger, System.Numerics.BigInteger)")
                    {
                        _Convert1by1(VM.OpCode.DIV, src, to);
                        return(0);
                    }
                    _Convert1by1(VM.OpCode.DIV, src, to);
                    return(0);
                }
                else if (src.tokenMethod.Contains("::op_Modulus("))
                {
                    //各类%指令
                    //有可能有一些会特殊处理,故还保留独立判断
                    if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Modulus(System.Numerics.BigInteger,System.Numerics.BigInteger)")
                    {
                        _Convert1by1(VM.OpCode.MOD, src, to);
                        return(0);
                    }
                    _Convert1by1(VM.OpCode.MOD, src, to);
                    return(0);
                }
                else if (src.tokenMethod.Contains("::op_LessThan("))
                {
                    //各类<指令
                    //有可能有一些会特殊处理,故还保留独立判断
                    _Convert1by1(VM.OpCode.LT, src, to);
                    return(0);
                }
                else if (src.tokenMethod.Contains("::op_GreaterThan("))
                {
                    //各类>指令
                    //有可能有一些会特殊处理,故还保留独立判断
                    _Convert1by1(VM.OpCode.GT, src, to);
                    return(0);
                }
                else if (src.tokenMethod.Contains("::op_LessThanOrEqual("))
                {
                    //各类<=指令
                    //有可能有一些会特殊处理,故还保留独立判断
                    _Convert1by1(VM.OpCode.LTE, src, to);
                    return(0);
                }
                else if (src.tokenMethod.Contains("::op_GreaterThanOrEqual("))
                {
                    //各类>=指令
                    //有可能有一些会特殊处理,故还保留独立判断
                    _Convert1by1(VM.OpCode.GTE, src, to);
                    return(0);
                }
                else if (src.tokenMethod.Contains("::get_Length("))
                {
                    //各类.Length指令
                    //"System.Int32 System.String::get_Length()"
                    _Convert1by1(VM.OpCode.SIZE, src, to);
                    return(0);
                }
                else if (src.tokenMethod.Contains("::Concat("))
                {
                    //各类.Concat
                    //"System.String System.String::Concat(System.String,System.String)"
                    _Convert1by1(VM.OpCode.CAT, src, to);
                    return(0);
                }

                else if (src.tokenMethod == "System.String System.String::Substring(System.Int32,System.Int32)")
                {
                    _Convert1by1(VM.OpCode.SUBSTR, src, to);
                    return(0);
                }
                else if (src.tokenMethod == "System.Char System.String::get_Chars(System.Int32)")
                {
                    _ConvertPush(1, src, to);
                    _Convert1by1(VM.OpCode.SUBSTR, null, to);
                    return(0);
                }
                else if (src.tokenMethod == "System.String System.String::Substring(System.Int32)")
                {
                    throw new Exception("neomachine cant use this call,please use  .SubString(1,2) with 2 params.");
                }
                else if (src.tokenMethod == "System.String System.Char::ToString()")
                {
                    return(0);
                }
                else if (src.tokenMethod == "System.Byte[] System.Numerics.BigInteger::ToByteArray()")
                {
                    return(0);
                }
                else if (src.tokenMethod == "System.Void System.Numerics.BigInteger::.ctor(System.Byte[])")
                {
                    _Convert1by1(VM.OpCode.DUPFROMALTSTACK, src, to);
                    _ConvertPush(2, null, to);
                    _Convert1by1(VM.OpCode.ROLL, null, to);
                    _ConvertPush(2, null, to);
                    _Convert1by1(VM.OpCode.ROLL, null, to);
                    _Convert1by1(VM.OpCode.SETITEM, null, to);
                    return(0);
                }
                else if (src.tokenMethod == "System.UInt32 <PrivateImplementationDetails>::ComputeStringHash(System.String)")
                {
                    throw new Exception("not supported on neovm now.");
                    // 需要neo.vm nuget更新以后,这个才可以放开,就可以处理 string switch了。");

                    //_Convert1by1(VM.OpCode.CSHARPSTRHASH32, src, to);
                    //return 0;
                }
                else
                {
                }
            }

            if (calltype == 0)
            {
                //之前的所有尝试都无效,那也不一定是个不存在的函数,有可能在别的模块里
                if (TryInsertMethod(outModule, defs))
                {
                    calltype = 1;
                    //ILModule module = new ILModule();
                    //module.LoadModule
                    //ILType type =new ILType()
                    //ILMethod method = new ILMethod(defs)
                }
                else
                {
                    throw new Exception("unknown call: " + src.tokenMethod + "\r\n   in: " + to.name + "\r\n");
                }
            }
            var  md       = src.tokenUnknown as Mono.Cecil.MethodReference;
            var  pcount   = md.Parameters.Count;
            bool havethis = md.HasThis;

            if (calltype == 2)
            {
                //opcode call
            }
            else
            {//翻转参数顺序
                //如果是syscall 并且有this的,翻转范围加一
                if (calltype == 3 && havethis)
                {
                    pcount++;
                }

                _Convert1by1(VM.OpCode.NOP, src, to);
                if (pcount <= 1)
                {
                }
                else if (pcount == 2)
                {
                    _Insert1(VM.OpCode.SWAP, "swap 2 param", to);
                }
                else if (pcount == 3)
                {
                    _InsertPush(2, "swap 0 and 2 param", to);
                    _Insert1(VM.OpCode.XSWAP, "", to);
                }
                else
                {
                    for (var i = 0; i < pcount / 2; i++)
                    {
                        int saveto = (pcount - 1 - i);
                        _InsertPush(saveto, "load" + saveto, to);
                        _Insert1(VM.OpCode.PICK, "", to);

                        _InsertPush(i + 1, "load" + i + 1, to);
                        _Insert1(VM.OpCode.PICK, "", to);


                        _InsertPush(saveto + 2, "save to" + saveto + 2, to);
                        _Insert1(VM.OpCode.XSWAP, "", to);
                        _Insert1(VM.OpCode.DROP, "", to);

                        _InsertPush(i + 1, "save to" + i + 1, to);
                        _Insert1(VM.OpCode.XSWAP, "", to);
                        _Insert1(VM.OpCode.DROP, "", to);
                    }
                }
            }
            if (calltype == 1)
            {
                if (this.outModule.option.useNep8)
                {
                    byte _pcount  = (byte)defs.Parameters.Count;
                    byte _rvcount = (byte)(defs.ReturnType.FullName == "System.Void" ? 0 : 1);
                    var  c        = _Convert1by1(VM.OpCode.CALL_I, null, to, new byte[] { _rvcount, _pcount, 0, 0 });
                    c.needfixfunc = true;
                    c.srcfunc     = src.tokenMethod;
                }
                else
                {
                    var c = _Convert1by1(VM.OpCode.CALL, null, to, new byte[] { 5, 0 });
                    c.needfixfunc = true;
                    c.srcfunc     = src.tokenMethod;
                }
                return(0);
            }
            else if (calltype == 2)
            {
                _Convert1by1(callcode, src, to);
                return(0);
            }
            else if (calltype == 3)
            {
                var bytes = Encoding.UTF8.GetBytes(callname);
                if (bytes.Length > 252)
                {
                    throw new Exception("string is to long");
                }
                byte[] outbytes = new byte[bytes.Length + 1];
                outbytes[0] = (byte)bytes.Length;
                Array.Copy(bytes, 0, outbytes, 1, bytes.Length);
                //bytes.Prepend 函数在 dotnet framework 4.6 编译不过
                _Convert1by1(VM.OpCode.SYSCALL, null, to, outbytes);
                return(0);
            }
            else if (calltype == 4)
            {
                if (this.outModule.option.useNep8)
                {
                    byte _pcount  = (byte)defs.Parameters.Count;
                    byte _rvcount = (byte)(defs.ReturnType.FullName == "System.Void" ? 0 : 1);
                    if (callhash.All(v => v == 0))//empty nep4
                    {
                        throw new Exception("nep4 calltype==6");
                    }
                    else
                    {
                        var bytes = new byte[] { _rvcount, _pcount }.Concat(callhash).ToArray();
                        _Convert1by1(VM.OpCode.CALL_E, null, to, bytes);
                    }
                }
                else
                {
                    _Convert1by1(VM.OpCode.APPCALL, null, to, callhash);
                }
            }
            else if (calltype == 5)
            {
                //把name参数推进去
                var callp = Encoding.UTF8.GetBytes(callname);
                _ConvertPush(callp, src, to);

                //参数打包成array
                _ConvertPush(pcount + 1, null, to);
                _Convert1by1(VM.OpCode.PACK, null, to);

                //a syscall
                {
                    var    bytes    = Encoding.UTF8.GetBytes("Neo.Runtime.Notify");
                    byte[] outbytes = new byte[bytes.Length + 1];
                    outbytes[0] = (byte)bytes.Length;
                    Array.Copy(bytes, 0, outbytes, 1, bytes.Length);
                    //bytes.Prepend 函数在 dotnet framework 4.6 编译不过
                    _Convert1by1(VM.OpCode.SYSCALL, null, to, outbytes);
                }
            }
            else if (calltype == 6)
            {
                _ConvertPush(callpcount, src, to);
                _Convert1by1(VM.OpCode.ROLL, null, to);
                //dyn appcall
                if (this.outModule.option.useNep8)
                {
                    byte _pcount  = (byte)defs.Parameters.Count;
                    byte _rvcount = (byte)(defs.ReturnType.FullName == "System.Void" ? 0 : 1);
                    //byte signature = (byte)(
                    //    (retcount << 7)
                    //    |
                    //    defs.Parameters.Count
                    //    );
                    _Convert1by1(VM.OpCode.CALL_ED, null, to, new byte[] { _rvcount, _pcount });
                }
                else
                {
                    byte[] nullhash = new byte[20];
                    _Convert1by1(VM.OpCode.APPCALL, null, to, nullhash);
                }
            }
            return(0);
        }
コード例 #18
0
        public static void Inject(string input_assembly_path, string output_assembly_path, string logger_assembly_path, string logger_type_name, string before_call_log_method_name, string log_attribute_name)
        {
            System.Diagnostics.Debug.Assert(System.IO.File.Exists(input_assembly_path));

            if (input_assembly_path != output_assembly_path)
            {
                if (System.IO.File.Exists(output_assembly_path))
                {
                    System.IO.File.Delete(output_assembly_path);
                }
                System.IO.File.Copy(input_assembly_path, output_assembly_path);
                System.Diagnostics.Debug.Assert(System.IO.File.Exists(output_assembly_path));
            }

            var    assembly_resolver        = new Mono.Cecil.DefaultAssemblyResolver();
            string input_assembly_directory = System.IO.Path.GetDirectoryName(input_assembly_path);

            assembly_resolver.AddSearchDirectory(input_assembly_directory);
            #if SILVERLIGHT
            Microsoft.Silverlight.Build.Tasks.GetSilverlightFrameworkPath path_task = new Microsoft.Silverlight.Build.Tasks.GetSilverlightFrameworkPath();
            path_task.RegistryBase = "Software\\Microsoft\\Microsoft SDKs\\Silverlight";
            path_task.Execute();
            assembly_resolver.AddSearchDirectory(path_task.SilverlightPath);
            foreach (string path in path_task.SilverlightSDKPaths)
            {
                assembly_resolver.AddSearchDirectory(path);
            }
            #endif
            Mono.Cecil.AssemblyDefinition injectible_assembly = Mono.Cecil.AssemblyDefinition.ReadAssembly(output_assembly_path, new Mono.Cecil.ReaderParameters {
                AssemblyResolver = assembly_resolver
            });

            System.Diagnostics.Debug.Assert(System.IO.File.Exists(logger_assembly_path));
            Mono.Cecil.AssemblyDefinition logger_assembly = Mono.Cecil.AssemblyDefinition.ReadAssembly(logger_assembly_path);
            Mono.Cecil.TypeDefinition     logger_type     = logger_assembly.MainModule.GetType(logger_type_name);
            System.Diagnostics.Debug.Assert(logger_type != null);
            Mono.Cecil.MethodDefinition before_callback_method_info = logger_type.Methods.First(m => m.Name == before_call_log_method_name);
            Mono.Cecil.MethodReference  before_callback_reference   = injectible_assembly.MainModule.Import(before_callback_method_info);

            //make sure to get System.Object.ToString method from assembly compatible with the injected assembly
            #if SILVERLIGHT
            string core_assembly_path = path_task.SilverlightPath + "mscorlib.dll";
            Mono.Cecil.AssemblyDefinition core_assembly         = Mono.Cecil.AssemblyDefinition.ReadAssembly(core_assembly_path);
            Mono.Cecil.TypeDefinition     object_type           = core_assembly.MainModule.GetType("System.Object");
            Mono.Cecil.MethodDefinition   to_string_method_info = object_type.Methods.First(m => m.Name == "ToString");
            #else
            System.Reflection.MethodInfo to_string_method_info = typeof(System.Object).GetMethod("ToString");
            #endif
            Mono.Cecil.MethodReference to_string_reference = injectible_assembly.MainModule.Import(to_string_method_info);

            foreach (Mono.Cecil.TypeDefinition type_definition in injectible_assembly.MainModule.Types)
            {
                bool is_type_logable = type_definition.CustomAttributes.Any(a => a.AttributeType.FullName == log_attribute_name);
                foreach (Mono.Cecil.MethodDefinition method_definition in type_definition.Methods)
                {
                    bool is_method_logable = is_type_logable || method_definition.CustomAttributes.Any(a => a.AttributeType.FullName == log_attribute_name);

                    if (is_method_logable)
                    {
                        Mono.Cecil.Cil.ILProcessor processor = method_definition.Body.GetILProcessor();

                        System.Collections.Generic.List <Mono.Cecil.Cil.Instruction> original_instructions = new System.Collections.Generic.List <Mono.Cecil.Cil.Instruction>();
                        original_instructions.AddRange(method_definition.Body.Instructions);
                        method_definition.Body.Instructions.Clear();

                        #region parameters

                        int method_parameters_count = method_definition.Parameters.Count;
                        int local_variables_count   = method_definition.Body.Variables.Count;
                        int arguments_array_index   = local_variables_count;

                        // Create an array of type System.String with the same number of elements as count of method parameters
                        // Add metadata for a new variable of type System.String[] to method body
                        // .locals init (System.String[] V_0)
                        Mono.Cecil.ArrayType arguments = new Mono.Cecil.ArrayType(injectible_assembly.MainModule.TypeSystem.String);
                        method_definition.Body.Variables.Add(new Mono.Cecil.Cil.VariableDefinition((Mono.Cecil.TypeReference)arguments));
                        method_definition.Body.InitLocals = true;
                        method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Ldc_I4, method_parameters_count));
                        method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Newarr, injectible_assembly.MainModule.TypeSystem.String));
                        // This instruction will store the address of the newly created array in the newly added local variable, which is at index = local_variables_count
                        method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Stloc, arguments_array_index));

                        #region parameters_to_string

                        // Instance methods have an an implicit argument called "this"
                        // so in that case we need to refer to actual arguments with +1 position
                        int parameter_offset = method_definition.IsStatic ? 0 : 1;
                        for (int i = 0; i < method_parameters_count; ++i)
                        {
                            // load argument array and current index
                            method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Ldloc, arguments_array_index));
                            method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Ldc_I4, i));

                            // load argument
                            method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Ldarga, i + parameter_offset));

                            // convert argument to string
                            Mono.Cecil.TypeReference argument_type = method_definition.Parameters[i].ParameterType;

                            method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Constrained, argument_type));
                            method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Callvirt, to_string_reference));

                            // store string in array
                            method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Stelem_Ref));
                        }

                        #endregion parameters_to_string

                        string method_signature = method_definition.ToString();
                        // load method signature
                        method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Ldstr, method_signature));

                        // load parameters array
                        method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Ldloc, arguments_array_index));

                        #endregion parameters

                        // load before call instruction
                        method_definition.Body.Instructions.Add(processor.Create(Mono.Cecil.Cil.OpCodes.Call, before_callback_reference));

                        foreach (var IL in original_instructions)
                        {
                            method_definition.Body.Instructions.Add(IL);
                        }
                    }
                }
            }

            injectible_assembly.Write(output_assembly_path);
        }
コード例 #19
0
ファイル: CompiledMethod.cs プロジェクト: PlumpMath/ac3il
 public void RegisterCall(Mono.Cecil.MethodReference t)
 {
     m_calls.Add(new KeyValuePair <int, Mono.Cecil.MethodReference>(m_instructionList.Count, t));
 }
コード例 #20
0
ファイル: Conv_Multi.cs プロジェクト: vardthomas/neo-compiler
        private int _ConvertCall(OpCode src, AntsMethod to)
        {
            Mono.Cecil.MethodReference refs = src.tokenUnknown as Mono.Cecil.MethodReference;

            int    calltype = 0;
            string callname = "";

            byte[]    callhash = null;
            VM.OpCode callcode = VM.OpCode.NOP;

            Mono.Cecil.MethodDefinition defs = null;
            try
            {
                defs = refs.Resolve();
            }
            catch
            {
            }
            if (IsNonCall(defs))
            {
                return(0);
            }
            else if (IsOpCall(defs, out callname))
            {
                if (System.Enum.TryParse <VM.OpCode>(callname, out callcode))
                {
                    calltype = 2;
                }
                else
                {
                    throw new Exception("Can not find OpCall:" + callname);
                }
            }
            else if (IsSysCall(defs, out callname))
            {
                calltype = 3;
            }
            else if (IsAppCall(defs, out callhash))
            {
                calltype = 4;
            }
            else if (this.outModule.mapMethods.ContainsKey(src.tokenMethod))
            {//this is a call
                calltype = 1;
            }
            else
            {//maybe a syscall // or other
                if (src.tokenMethod.Contains("::op_Explicit(") || src.tokenMethod.Contains("::op_Implicit("))
                {
                    //各类显示隐示转换都忽略
                    //有可能有一些会特殊处理,故还保留独立判断
                    if (src.tokenMethod == "System.Int32 System.Numerics.BigInteger::op_Explicit(System.Numerics.BigInteger)")
                    {
                        //donothing
                        return(0);
                    }
                    else if (src.tokenMethod == "System.Int64 System.Numerics.BigInteger::op_Explicit(System.Numerics.BigInteger)")
                    {
                        //donothing
                        return(0);
                    }
                    else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Implicit(System.Int32)")//int->bignumber
                    {
                        //donothing
                        return(0);
                    }
                    else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Implicit(System.Int64)")
                    {
                        return(0);
                    }

                    return(0);
                }
                else if (src.tokenMethod == "System.Void System.Diagnostics.Debugger::Break()")
                {
                    _Convert1by1(VM.OpCode.NOP, src, to);

                    return(0);
                }
                else if (src.tokenMethod.Contains("::op_Equality(") || src.tokenMethod.Contains("::Equals("))
                {
                    //各类==指令
                    //有可能有一些会特殊处理,故还保留独立判断
                    if (src.tokenMethod == "System.Boolean System.String::op_Equality(System.String,System.String)")
                    {
                        _Convert1by1(VM.OpCode.EQUAL, src, to);
                        return(0);
                    }
                    else if (src.tokenMethod == "System.Boolean System.Object::Equals(System.Object)")
                    {
                        _Convert1by1(VM.OpCode.EQUAL, src, to);
                        return(0);
                    }
                    _Convert1by1(VM.OpCode.EQUAL, src, to);
                    return(0);
                }
                else if (src.tokenMethod.Contains("::op_Inequality("))
                {
                    //各类!=指令
                    //有可能有一些会特殊处理,故还保留独立判断
                    if (src.tokenMethod == "System.Boolean System.Numerics.BigInteger::op_Inequality(System.Numerics.BigInteger,System.Numerics.BigInteger)")
                    {
                        _Convert1by1(VM.OpCode.INVERT, src, to);
                        _Insert1(VM.OpCode.EQUAL, "", to);
                        return(0);
                    }
                    _Convert1by1(VM.OpCode.INVERT, src, to);
                    _Insert1(VM.OpCode.EQUAL, "", to);
                    return(0);
                }
                else if (src.tokenMethod.Contains("::op_Addition("))
                {
                    //各类+指令
                    //有可能有一些会特殊处理,故还保留独立判断
                    if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Addition(System.Numerics.BigInteger,System.Numerics.BigInteger)")
                    {
                        _Convert1by1(VM.OpCode.ADD, src, to);
                        return(0);
                    }
                    _Convert1by1(VM.OpCode.ADD, src, to);
                    return(0);
                }
                else if (src.tokenMethod.Contains("::op_Subtraction("))
                {
                    //各类-指令
                    //有可能有一些会特殊处理,故还保留独立判断
                    if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Subtraction(System.Numerics.BigInteger,System.Numerics.BigInteger)")
                    {
                        _Convert1by1(VM.OpCode.SUB, src, to);
                        return(0);
                    }
                    _Convert1by1(VM.OpCode.SUB, src, to);
                    return(0);
                }
                else if (src.tokenMethod.Contains("::op_Multiply("))
                {
                    //各类*指令
                    //有可能有一些会特殊处理,故还保留独立判断
                    if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Multiply(System.Numerics.BigInteger,System.Numerics.BigInteger)")
                    {
                        _Convert1by1(VM.OpCode.MUL, src, to);
                        return(0);
                    }
                    _Convert1by1(VM.OpCode.MUL, src, to);
                    return(0);
                }
                else if (src.tokenMethod.Contains("::op_Division("))
                {
                    //各类/指令
                    //有可能有一些会特殊处理,故还保留独立判断
                    if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Division(System.Numerics.BigInteger, System.Numerics.BigInteger)")
                    {
                        _Convert1by1(VM.OpCode.DIV, src, to);
                        return(0);
                    }
                    _Convert1by1(VM.OpCode.DIV, src, to);
                    return(0);
                }
                else if (src.tokenMethod.Contains("::op_Modulus("))
                {
                    //各类%指令
                    //有可能有一些会特殊处理,故还保留独立判断
                    if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Modulus(System.Numerics.BigInteger,System.Numerics.BigInteger)")
                    {
                        _Convert1by1(VM.OpCode.MOD, src, to);
                        return(0);
                    }
                    _Convert1by1(VM.OpCode.MOD, src, to);
                    return(0);
                }
                else if (src.tokenMethod.Contains("::op_LessThan("))
                {
                    //各类<指令
                    //有可能有一些会特殊处理,故还保留独立判断
                    _Convert1by1(VM.OpCode.LT, src, to);
                    return(0);
                }
                else if (src.tokenMethod.Contains("::op_GreaterThan("))
                {
                    //各类>指令
                    //有可能有一些会特殊处理,故还保留独立判断
                    _Convert1by1(VM.OpCode.GT, src, to);
                    return(0);
                }
                else if (src.tokenMethod.Contains("::op_LessThanOrEqual("))
                {
                    //各类<=指令
                    //有可能有一些会特殊处理,故还保留独立判断
                    _Convert1by1(VM.OpCode.LTE, src, to);
                    return(0);
                }
                else if (src.tokenMethod.Contains("::op_GreaterThanOrEqual("))
                {
                    //各类>=指令
                    //有可能有一些会特殊处理,故还保留独立判断
                    _Convert1by1(VM.OpCode.GTE, src, to);
                    return(0);
                }
                else if (src.tokenMethod.Contains("::get_Length("))
                {
                    //各类.Length指令
                    //"System.Int32 System.String::get_Length()"
                    _Convert1by1(VM.OpCode.SIZE, src, to);
                    return(0);
                }
                else if (src.tokenMethod.Contains("::Concat("))
                {
                    //各类.Concat
                    //"System.String System.String::Concat(System.String,System.String)"
                    _Convert1by1(VM.OpCode.CAT, src, to);
                    return(0);
                }

                else if (src.tokenMethod == "System.String System.String::Substring(System.Int32,System.Int32)")
                {
                    _Convert1by1(VM.OpCode.SUBSTR, src, to);
                    return(0);
                }
                else if (src.tokenMethod == "System.Char System.String::get_Chars(System.Int32)")
                {
                    _ConvertPush(1, src, to);
                    _Convert1by1(VM.OpCode.SUBSTR, null, to);
                    return(0);
                }
                else if (src.tokenMethod == "System.String System.String::Substring(System.Int32)")
                {
                    throw new Exception("antsmachine cant use this call,please use  .SubString(1,2) with 2 params.");
                }
                else if (src.tokenMethod == "System.String System.Char::ToString()")
                {
                    return(0);
                }
                else if (src.tokenMethod == "System.Byte[] System.Numerics.BigInteger::ToByteArray()")
                {
                    return(0);
                }
                else if (src.tokenMethod == "System.Void System.Numerics.BigInteger::.ctor(System.Byte[])")
                {
                    _Convert1by1(VM.OpCode.DUPFROMALTSTACK, src, to);
                    _ConvertPush(2, null, to);
                    _Convert1by1(VM.OpCode.ROLL, null, to);
                    _ConvertPush(2, null, to);
                    _Convert1by1(VM.OpCode.ROLL, null, to);
                    _Convert1by1(VM.OpCode.SETITEM, null, to);
                    return(0);
                }
                else
                {
                }
            }

            if (calltype == 0)
            {
                throw new Exception("unknown call:" + src.tokenMethod);
            }
            var md     = src.tokenUnknown as Mono.Cecil.MethodReference;
            var pcount = md.Parameters.Count;

            _Convert1by1(VM.OpCode.NOP, src, to);
            if (pcount <= 1)
            {
            }
            else if (pcount == 2)
            {
                _Insert1(VM.OpCode.SWAP, "swap 2 param", to);
            }
            else if (pcount == 3)
            {
                _InsertPush(2, "swap 0 and 2 param", to);
                _Insert1(VM.OpCode.XSWAP, "", to);
            }
            else
            {
                for (var i = 0; i < pcount / 2; i++)
                {
                    int saveto = (pcount - 1 - i);
                    _InsertPush(saveto, "load" + saveto, to);
                    _Insert1(VM.OpCode.PICK, "", to);

                    _InsertPush(i + 1, "load" + i + 1, to);
                    _Insert1(VM.OpCode.PICK, "", to);


                    _InsertPush(saveto + 2, "save to" + saveto + 2, to);
                    _Insert1(VM.OpCode.XSWAP, "", to);
                    _Insert1(VM.OpCode.DROP, "", to);

                    _InsertPush(i + 1, "save to" + i + 1, to);
                    _Insert1(VM.OpCode.XSWAP, "", to);
                    _Insert1(VM.OpCode.DROP, "", to);
                }
            }

            if (calltype == 1)
            {
                var c = _Convert1by1(VM.OpCode.CALL, null, to, new byte[] { 5, 0 });
                c.needfix = true;
                c.srcfunc = src.tokenMethod;
                return(0);
            }
            else if (calltype == 2)
            {
                _Convert1by1(callcode, null, to);
                return(0);
            }
            else if (calltype == 3)
            {
                var bytes = Encoding.UTF8.GetBytes(callname);
                if (bytes.Length > 252)
                {
                    throw new Exception("string is to long");
                }
                byte[] outbytes = new byte[bytes.Length + 1];
                outbytes[0] = (byte)bytes.Length;
                Array.Copy(bytes, 0, outbytes, 1, bytes.Length);
                //bytes.Prepend 函数在 dotnet framework 4.6 编译不过
                _Convert1by1(VM.OpCode.SYSCALL, null, to, outbytes);
                return(0);
            }
            else if (calltype == 4)
            {
                _Convert1by1(VM.OpCode.APPCALL, null, to, callhash);
            }
            return(0);
        }
コード例 #21
0
ファイル: Conv_Multi.cs プロジェクト: luodanwg/AntShares.VM
        private int _ConvertCall(OpCode src, AntsMethod to)
        {
            Mono.Cecil.MethodReference refs = src.tokenUnknown as Mono.Cecil.MethodReference;

            int    calltype = 0;
            string callname = "";

            VM.OpCode callcode = VM.OpCode.NOP;
            if (this.outModule.mapMethods.ContainsKey(src.tokenMethod))
            {//this is a call
                calltype = 1;
            }
            else if (refs.ReturnType.Name == "ExecutionEngine" || refs.ReturnType.Name == "Storage")
            {
                if (src != null)
                {
                    //有可能jump到此处
                    this.addrconv[src.addr] = this.addr;//因为没插入代码,实际是下一行
                }
                //donothing 語法過渡類型
                return(0);
            }
            else
            {//maybe a syscall // or other
                if (src.tokenMethod == "System.Int32 System.Numerics.BigInteger::op_Explicit(System.Numerics.BigInteger)")
                {
                    //donothing
                    return(0);
                }
                if (src.tokenMethod == "System.Int32 System.Numerics.BigInteger::op_Explicit(System.Numerics.BigInteger)")
                {
                    //donothing
                    return(0);
                }
                else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Implicit(System.Int32)")//int->bignumber
                {
                    //donothing
                    return(0);
                }
                else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Implicit(System.Int64)")
                {
                    return(0);
                }
                if (src.tokenMethod.Contains("::op_Equality(") || src.tokenMethod.Contains("::Equals("))
                {
                    _Convert1by1(AntShares.VM.OpCode.EQUAL, src, to);
                    return(0);
                }
                else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Addition(System.Numerics.BigInteger,System.Numerics.BigInteger)")
                {
                    _Convert1by1(AntShares.VM.OpCode.ADD, src, to);
                    return(0);
                }
                else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Subtraction(System.Numerics.BigInteger,System.Numerics.BigInteger)")
                {
                    _Convert1by1(AntShares.VM.OpCode.SUB, src, to);
                    return(0);
                }
                else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Multiply(System.Numerics.BigInteger,System.Numerics.BigInteger)")
                {
                    _Convert1by1(AntShares.VM.OpCode.MUL, src, to);
                    return(0);
                }
                else if (src.tokenMethod == "System.Boolean System.Numerics.BigInteger::op_LessThanOrEqual(System.Numerics.BigInteger,System.Int64)")
                {
                    _Convert1by1(AntShares.VM.OpCode.LTE, src, to);
                    return(0);
                }
                else if (src.tokenMethod == "System.Boolean System.Numerics.BigInteger::op_LessThan(System.Numerics.BigInteger,System.Numerics.BigInteger)")
                {
                    _Convert1by1(AntShares.VM.OpCode.LT, src, to);
                    return(0);
                }
                else if (src.tokenMethod == "System.Boolean System.Numerics.BigInteger::op_GreaterThan(System.Numerics.BigInteger,System.Numerics.BigInteger)")
                {
                    _Convert1by1(AntShares.VM.OpCode.GT, src, to);
                    return(0);
                }
                else
                {
                    if (IsOpCall(refs, out callname))
                    {
                        if (callname == "CHECKSIG")
                        {
                            callcode = VM.OpCode.CHECKSIG;
                            calltype = 2;
                        }
                    }
                    if (IsSysCall(refs, out callname))
                    {
                        calltype = 3;
                    }
                }
            }

            if (calltype == 0)
            {
                throw new Exception("unknown call:" + src.tokenMethod);
            }
            var md     = src.tokenUnknown as Mono.Cecil.MethodReference;
            var pcount = md.Parameters.Count;

            _Convert1by1(VM.OpCode.NOP, src, to);
            if (pcount <= 1)
            {
            }
            else if (pcount == 2)
            {
                _Insert1(VM.OpCode.SWAP, "swap 2 param", to);
            }
            else if (pcount == 3)
            {
                _InsertPush(2, "swap 0 and 2 param", to);
                _Insert1(VM.OpCode.XSWAP, "", to);
            }
            else
            {
                for (var i = 0; i < pcount / 2; i++)
                {
                    int saveto = (pcount - 1 - i);
                    _InsertPush(saveto, "load" + saveto, to);
                    _Insert1(VM.OpCode.PICK, "", to);

                    _InsertPush(i + 1, "load" + i + 1, to);
                    _Insert1(VM.OpCode.PICK, "", to);


                    _InsertPush(saveto + 2, "save to" + saveto + 2, to);
                    _Insert1(VM.OpCode.XSWAP, "", to);
                    _Insert1(VM.OpCode.DROP, "", to);

                    _InsertPush(i + 1, "save to" + i + 1, to);
                    _Insert1(VM.OpCode.XSWAP, "", to);
                    _Insert1(VM.OpCode.DROP, "", to);
                }
            }

            if (calltype == 1)
            {
                var c = _Convert1by1(AntShares.VM.OpCode.CALL, null, to, new byte[] { 5, 0 });
                c.needfix = true;
                c.srcfunc = src.tokenMethod;
                return(0);
            }
            else if (calltype == 2)
            {
                _Convert1by1(callcode, null, to);
                return(0);
            }
            else if (calltype == 3)
            {
                var bytes = Encoding.UTF8.GetBytes(callname);
                if (bytes.Length > 252)
                {
                    throw new Exception("string is to long");
                }
                byte[] outbytes = new byte[bytes.Length + 1];
                outbytes[0] = (byte)bytes.Length;
                Array.Copy(bytes, 0, outbytes, 1, bytes.Length);
                //bytes.Prepend 函数在 dotnet framework 4.6 编译不过
                _Convert1by1(AntShares.VM.OpCode.SYSCALL, null, to, outbytes);
                return(0);
            }
            return(0);
        }
コード例 #22
0
 private static void ConvertMethodDefinition(MethodReference method, TypeReference enumType)
 {
     if (method.ReturnType.FullName == SystemEnumName)
         method.ReturnType = enumType;
     foreach (var p in method.Parameters)
         if (p.ParameterType.FullName == SystemEnumName)
             p.ParameterType = enumType;
 }
コード例 #23
0
ファイル: Type_List.cs プロジェクト: sjb8100/LSharp
        ICLRType GetTType(ICLRSharp_Environment env, Mono.Cecil.ParameterDefinition param, Mono.Cecil.MethodReference method, MethodParamList _methodgen)
        {
            string typename = param.ParameterType.FullName;

            for (int i = 0; i < _methodgen.Count; i++)
            {
                string p = "!!" + i.ToString();
                typename = typename.Replace(p, _methodgen[i].FullName);
            }
            return(env.GetType(typename, method.Module));
        }
コード例 #24
0
 public static void CallVirtual(Mono.Cecil.MethodReference method)
 {
     CurrentEmitContext.Emit(CreateInstruction.CallVirtual(method));
 }
コード例 #25
0
        private int _ConvertCall(OpCode src, AntsMethod to)
        {
            Mono.Cecil.MethodReference refs = src.tokenUnknown as Mono.Cecil.MethodReference;

            int    calltype = 0;
            string callname = "";

            VM.OpCode callcode = VM.OpCode.NOP;
            if (this.outModule.mapMethods.ContainsKey(src.tokenMethod))
            {//this is a call
                calltype = 1;
            }
            else if (refs.ReturnType.Name == "ExecutionEngine")
            {
                //donothing 語法過渡類型
                return(0);
            }
            else
            {//maybe a syscall // or other
                if (src.tokenMethod == "System.Int32 System.Numerics.BigInteger::op_Explicit(System.Numerics.BigInteger)")
                {
                    //donothing
                    return(0);
                }
                else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Implicit(System.Int32)")//int->bignumber
                {
                    //donothing
                    return(0);
                }
                else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Implicit(System.Int64)")
                {
                    return(0);
                }
                else if (src.tokenMethod == "System.Boolean System.Object::Equals(System.Object)")
                {
                    _Convert1by1(AntShares.VM.OpCode.EQUAL, src, to);
                    return(0);
                }
                else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Addition(System.Numerics.BigInteger,System.Numerics.BigInteger)")
                {
                    _Convert1by1(AntShares.VM.OpCode.ADD, src, to);
                    return(0);
                }
                else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Subtraction(System.Numerics.BigInteger,System.Numerics.BigInteger)")
                {
                    _Convert1by1(AntShares.VM.OpCode.SUB, src, to);
                    return(0);
                }
                else if (src.tokenMethod == "System.Numerics.BigInteger System.Numerics.BigInteger::op_Multiply(System.Numerics.BigInteger,System.Numerics.BigInteger)")
                {
                    _Convert1by1(AntShares.VM.OpCode.MUL, src, to);
                    return(0);
                }
                else if (src.tokenMethod == "System.Boolean System.Numerics.BigInteger::op_LessThanOrEqual(System.Numerics.BigInteger,System.Int64)")
                {
                    _Convert1by1(AntShares.VM.OpCode.LTE, src, to);
                    return(0);
                }
                else if (src.tokenMethod == "System.Boolean System.Numerics.BigInteger::op_LessThan(System.Numerics.BigInteger,System.Numerics.BigInteger)")
                {
                    _Convert1by1(AntShares.VM.OpCode.LT, src, to);
                    return(0);
                }
                else if (src.tokenMethod == "System.Boolean System.Numerics.BigInteger::op_GreaterThan(System.Numerics.BigInteger,System.Numerics.BigInteger)")
                {
                    _Convert1by1(AntShares.VM.OpCode.GT, src, to);
                    return(0);
                }
                else
                {
                    if (IsOpCall(refs, out callname))
                    {
                        if (callname == "CHECKSIG")
                        {
                            callcode = VM.OpCode.CHECKSIG;
                            calltype = 2;
                        }
                    }
                    if (IsSysCall(refs, out callname))
                    {
                        calltype = 3;
                    }
                }
            }

            if (calltype == 0)
            {
                throw new Exception("unknown call:" + src.tokenMethod);
            }
            var md     = src.tokenUnknown as Mono.Cecil.MethodReference;
            var pcount = md.Parameters.Count;

            _Convert1by1(VM.OpCode.NOP, src, to);
            if (pcount <= 1)
            {
            }
            else if (pcount == 2)
            {
                _Insert1(VM.OpCode.SWAP, "swap 2 param", to);
            }
            else if (pcount == 3)
            {
                _Insert1(VM.OpCode.PUSHDATA1, "swap 0 and 2 param", to, int2Pushdata1bytes(2));
                _Insert1(VM.OpCode.XSWAP, "", to);
            }
            else
            {
                for (var i = 0; i < pcount / 2; i++)
                {
                    int saveto = (pcount - 1 - i);
                    _Insert1(VM.OpCode.PUSHDATA1, "load" + saveto, to, int2Pushdata1bytes(saveto));
                    _Insert1(VM.OpCode.PICK, "", to);

                    _Insert1(VM.OpCode.PUSHDATA1, "load" + i + 1, to, int2Pushdata1bytes(i + 1));
                    _Insert1(VM.OpCode.PICK, "", to);


                    _Insert1(VM.OpCode.PUSHDATA1, "save to" + saveto + 2, to, int2Pushdata1bytes(saveto + 2));
                    _Insert1(VM.OpCode.XSWAP, "", to);
                    _Insert1(VM.OpCode.DROP, "", to);

                    _Insert1(VM.OpCode.PUSHDATA1, "save to" + i + 1, to, int2Pushdata1bytes(i + 1));
                    _Insert1(VM.OpCode.XSWAP, "", to);
                    _Insert1(VM.OpCode.DROP, "", to);
                }
            }

            if (calltype == 1)
            {
                var c = _Convert1by1(AntShares.VM.OpCode.CALL, null, to, new byte[] { 5, 0 });
                c.needfix = true;
                c.srcfunc = src.tokenMethod;
                return(0);
            }
            else if (calltype == 2)
            {
                _Convert1by1(callcode, null, to);
                return(0);
            }
            else if (calltype == 3)
            {
                _Convert1by1(AntShares.VM.OpCode.SYSCALL, null, to, str2Pushdata1bytes(callname));
                return(0);
            }
            return(0);
        }
コード例 #26
0
        private void AssignReturnType()
        {
            IsReturnTypeRef = false;

            switch (Instruction.OpCode.StackBehaviourPush)
            {
            case Mono.Cecil.Cil.StackBehaviour.Push0:
                ReturnType = null;
                break;

            case Mono.Cecil.Cil.StackBehaviour.Push1:
                switch (Instruction.OpCode.Code)
                {
                //These return the argument type
                case Mono.Cecil.Cil.Code.Ldarg_0:
                    ReturnType = Type.GetType(ParentMethod.Parameters[0].ParameterType.FullName);
                    break;

                case Mono.Cecil.Cil.Code.Ldarg_1:
                    ReturnType = Type.GetType(ParentMethod.Parameters[1].ParameterType.FullName);
                    break;

                case Mono.Cecil.Cil.Code.Ldarg_2:
                    ReturnType = Type.GetType(ParentMethod.Parameters[2].ParameterType.FullName);
                    break;

                case Mono.Cecil.Cil.Code.Ldarg_3:
                    ReturnType = Type.GetType(ParentMethod.Parameters[3].ParameterType.FullName);
                    break;

                case Mono.Cecil.Cil.Code.Ldarg_S:
                case Mono.Cecil.Cil.Code.Ldarg:
                    ReturnType = Type.GetType(ParentMethod.Parameters[((int)Instruction.Operand)].ParameterType.FullName);
                    break;

                //These return the local variable type
                case Mono.Cecil.Cil.Code.Ldloc_0:
                    ReturnType = Type.GetType(ParentMethod.Body.Variables[0].VariableType.FullName);
                    break;

                case Mono.Cecil.Cil.Code.Ldloc_1:
                    ReturnType = Type.GetType(ParentMethod.Body.Variables[1].VariableType.FullName);
                    break;

                case Mono.Cecil.Cil.Code.Ldloc_2:
                    ReturnType = Type.GetType(ParentMethod.Body.Variables[2].VariableType.FullName);
                    break;

                case Mono.Cecil.Cil.Code.Ldloc_3:
                    ReturnType = Type.GetType(ParentMethod.Body.Variables[3].VariableType.FullName);
                    break;

                case Mono.Cecil.Cil.Code.Ldloc_S:
                case Mono.Cecil.Cil.Code.Ldloc:
                    ReturnType = Type.GetType(ParentMethod.Body.Variables[((Mono.Cecil.Cil.VariableReference)(Instruction.Operand)).Index].VariableType.FullName);
                    break;

                //These return the same type as their source operands
                case Mono.Cecil.Cil.Code.Add:
                case Mono.Cecil.Cil.Code.Sub:
                case Mono.Cecil.Cil.Code.Mul:
                case Mono.Cecil.Cil.Code.Div:
                case Mono.Cecil.Cil.Code.Rem:
                case Mono.Cecil.Cil.Code.And:
                case Mono.Cecil.Cil.Code.Or:
                case Mono.Cecil.Cil.Code.Xor:
                case Mono.Cecil.Cil.Code.Shl:
                case Mono.Cecil.Cil.Code.Shr:
                case Mono.Cecil.Cil.Code.Neg:
                case Mono.Cecil.Cil.Code.Not:
                case Mono.Cecil.Cil.Code.Div_Un:
                case Mono.Cecil.Cil.Code.Rem_Un:
                case Mono.Cecil.Cil.Code.Shr_Un:
                case Mono.Cecil.Cil.Code.Add_Ovf:
                case Mono.Cecil.Cil.Code.Add_Ovf_Un:
                case Mono.Cecil.Cil.Code.Mul_Ovf:
                case Mono.Cecil.Cil.Code.Mul_Ovf_Un:
                case Mono.Cecil.Cil.Code.Sub_Ovf:
                case Mono.Cecil.Cil.Code.Sub_Ovf_Un:
                    if (Childnodes[0].IsReturnTypeRef)
                    {
                        throw new Exception("Unexpected operands");
                    }
                    ReturnType = Childnodes[0].ReturnType;
                    break;

                case Mono.Cecil.Cil.Code.Ldobj:
                    if (!Childnodes[0].IsReturnTypeRef)
                    {
                        throw new Exception("Ldobj from something that is not an array?");
                    }

                    ReturnType      = Childnodes[0].ReturnType;
                    IsReturnTypeRef = false;
                    break;

                //These are not fixed yet
                case Mono.Cecil.Cil.Code.Mkrefany:
                case Mono.Cecil.Cil.Code.Ldelem_Any:
                case Mono.Cecil.Cil.Code.Ldsfld:
                case Mono.Cecil.Cil.Code.Ldfld:
                    throw new Exception("The opcode is not supported for Push1: " + Instruction.OpCode.Code);

                case Mono.Cecil.Cil.Code.Unbox_Any:
                    ReturnType      = Type.GetType(((Mono.Cecil.TypeReference)Instruction.Operand).FullName);
                    IsReturnTypeRef = false;
                    break;

                default:
                    throw new Exception("Unexpected Push1 operation: " + Instruction.OpCode.Code);
                }
                break;

            case Mono.Cecil.Cil.StackBehaviour.Push1_push1:
                //AFAIK, the only instruction that does this is the dup instruction
                System.Diagnostics.Trace.Assert(Instruction.OpCode.Code == Mono.Cecil.Cil.Code.Dup);
                ReturnType      = Childnodes[0].ReturnType;
                IsReturnTypeRef = Childnodes[0].IsReturnTypeRef;
                break;

            case Mono.Cecil.Cil.StackBehaviour.Pushi:
                //This can actually also be an adress
                switch (Instruction.OpCode.Code)
                {
                case Mono.Cecil.Cil.Code.Ldelema:
                    if (!Childnodes[0].ReturnType.IsArray)
                    {
                        throw new Exception("Ldelem a for type which is not an array: " + Childnodes[0].ReturnType.FullName);
                    }

                    ReturnType      = Childnodes[0].ReturnType.GetElementType();
                    IsReturnTypeRef = true;
                    break;

                case Mono.Cecil.Cil.Code.Ldc_I4:
                case Mono.Cecil.Cil.Code.Ldc_I4_0:
                case Mono.Cecil.Cil.Code.Ldc_I4_1:
                case Mono.Cecil.Cil.Code.Ldc_I4_2:
                case Mono.Cecil.Cil.Code.Ldc_I4_3:
                case Mono.Cecil.Cil.Code.Ldc_I4_4:
                case Mono.Cecil.Cil.Code.Ldc_I4_5:
                case Mono.Cecil.Cil.Code.Ldc_I4_6:
                case Mono.Cecil.Cil.Code.Ldc_I4_7:
                case Mono.Cecil.Cil.Code.Ldc_I4_8:
                case Mono.Cecil.Cil.Code.Ldc_I4_M1:
                case Mono.Cecil.Cil.Code.Ldc_I4_S:
                case Mono.Cecil.Cil.Code.Ldlen:
                case Mono.Cecil.Cil.Code.Conv_I1:
                case Mono.Cecil.Cil.Code.Conv_I2:
                case Mono.Cecil.Cil.Code.Conv_I4:
                case Mono.Cecil.Cil.Code.Conv_U4:
                case Mono.Cecil.Cil.Code.Isinst:
                case Mono.Cecil.Cil.Code.Conv_Ovf_I1:
                case Mono.Cecil.Cil.Code.Conv_Ovf_I2:
                case Mono.Cecil.Cil.Code.Conv_Ovf_I4:
                case Mono.Cecil.Cil.Code.Conv_Ovf_U1:
                case Mono.Cecil.Cil.Code.Conv_Ovf_U2:
                case Mono.Cecil.Cil.Code.Conv_Ovf_U4:
                case Mono.Cecil.Cil.Code.Refanyval:
                case Mono.Cecil.Cil.Code.Ldtoken:
                case Mono.Cecil.Cil.Code.Conv_U1:
                case Mono.Cecil.Cil.Code.Conv_U2:
                case Mono.Cecil.Cil.Code.Conv_I:
                case Mono.Cecil.Cil.Code.Conv_U:
                case Mono.Cecil.Cil.Code.Conv_Ovf_I:
                case Mono.Cecil.Cil.Code.Conv_Ovf_U:
                case Mono.Cecil.Cil.Code.Arglist:
                case Mono.Cecil.Cil.Code.Ceq:
                case Mono.Cecil.Cil.Code.Cgt:
                case Mono.Cecil.Cil.Code.Cgt_Un:
                case Mono.Cecil.Cil.Code.Clt:
                case Mono.Cecil.Cil.Code.Clt_Un:
                case Mono.Cecil.Cil.Code.Sizeof:
                case Mono.Cecil.Cil.Code.Refanytype:
                case Mono.Cecil.Cil.Code.Ldelem_I:
                case Mono.Cecil.Cil.Code.Ldelem_I4:
                    ReturnType = typeof(int);
                    break;

                case Mono.Cecil.Cil.Code.Ldelem_I1:
                    ReturnType = typeof(sbyte);
                    break;

                case Mono.Cecil.Cil.Code.Ldelem_I2:
                    ReturnType = typeof(short);
                    break;

                case Mono.Cecil.Cil.Code.Ldelem_I8:
                    ReturnType = typeof(long);
                    break;

                case Mono.Cecil.Cil.Code.Ldelem_R4:
                    ReturnType = typeof(float);
                    break;

                case Mono.Cecil.Cil.Code.Ldelem_R8:
                    ReturnType = typeof(double);
                    break;

                case Mono.Cecil.Cil.Code.Ldelem_U1:
                    ReturnType = typeof(byte);
                    break;

                case Mono.Cecil.Cil.Code.Ldelem_U2:
                    ReturnType = typeof(ushort);
                    break;

                case Mono.Cecil.Cil.Code.Ldelem_U4:
                    ReturnType = typeof(uint);
                    break;

                default:
                    throw new Exception("Unexpected Pushi instruction: " + Instruction.OpCode.Code);
                }

                break;

            case Mono.Cecil.Cil.StackBehaviour.Pushi8:
                /*switch (instruction.OpCode.Code)
                 * {
                 *  case Mono.Cecil.Cil.Code.Ldc_I8:
                 *  case Mono.Cecil.Cil.Code.Ldind_I8:
                 *  case Mono.Cecil.Cil.Code.Conv_I8:
                 *  case Mono.Cecil.Cil.Code.Conv_Ovf_I8:
                 *  case Mono.Cecil.Cil.Code.Conv_Ovf_I8_Un:
                 *  case Mono.Cecil.Cil.Code.Ldelem_I8:
                 *      ReturnType = typeof(long);
                 *      break;
                 *  case Mono.Cecil.Cil.Code.Conv_U8:
                 *  case Mono.Cecil.Cil.Code.Conv_Ovf_U8:
                 *  case Mono.Cecil.Cil.Code.Conv_Ovf_U8_Un:
                 *      ReturnType = typeof(ulong);
                 *      break;
                 *  default:
                 *      throw new Exception("Unexpected Pushi8 operation");
                 * }*/
                //According to ECMA spec:
                // Special instructions are used to interpret integers on the stack as though they were unsigned, rather than tagging the stack locations as being unsigned.
                ReturnType = typeof(long);
                break;

            case Mono.Cecil.Cil.StackBehaviour.Pushr4:
                ReturnType = typeof(float);
                break;

            case Mono.Cecil.Cil.StackBehaviour.Pushr8:
                ReturnType = typeof(double);
                break;

            case Mono.Cecil.Cil.StackBehaviour.Varpush:
                //Instruction is supposed to be a call type function
                System.Diagnostics.Trace.Assert(Instruction.OpCode.Code == Mono.Cecil.Cil.Code.Call || Instruction.OpCode.Code == Mono.Cecil.Cil.Code.Calli || Instruction.OpCode.Code == Mono.Cecil.Cil.Code.Callvirt);
                Mono.Cecil.MethodReference mdef = ((Mono.Cecil.MethodReference)Instruction.Operand);
                switch (mdef.ReturnType.ReturnType.FullName)
                {
                case "System.Void":
                    ReturnType = null;
                    break;

                case "System.Byte":
                case "System.SByte":
                case "System.Boolean":
                case "System.Int16":
                case "System.Int32":
                case "System.UInt16":
                case "System.UInt32":
                    ReturnType = typeof(int);
                    break;

                case "System.Int64":
                case "System.UInt64":
                    ReturnType = typeof(long);
                    break;

                case "System.Float":
                    ReturnType = typeof(float);
                    break;

                case "System.Double":
                    ReturnType = typeof(double);
                    break;

                default:
                    ReturnType      = Type.GetType(mdef.ReturnType.ReturnType.FullName);
                    IsReturnTypeRef = true;
                    break;
                }
                break;

            case Mono.Cecil.Cil.StackBehaviour.Pushref:
                IsReturnTypeRef = true;
                switch (Instruction.OpCode.Code)
                {
                case Mono.Cecil.Cil.Code.Ldnull:
                    System.Diagnostics.Trace.Assert(true, "Figure out how to extract the class type");
                    ReturnType = null;         //TODO: can we infer the type somehow?
                    break;

                case Mono.Cecil.Cil.Code.Ldind_Ref:
                    System.Diagnostics.Trace.Assert(true, "Figure out how to extract the class type");
                    ReturnType = null;         //TODO: How do we guess this?
                    break;

                case Mono.Cecil.Cil.Code.Ldstr:
                    ReturnType = typeof(string);
                    break;

                case Mono.Cecil.Cil.Code.Newobj:
                case Mono.Cecil.Cil.Code.Castclass:
                    System.Diagnostics.Trace.Assert(true, "Figure out how to extract the class type");
                    ReturnType = ExtractClassType((Mono.Cecil.MemberReference)Instruction.Operand);
                    break;

                case Mono.Cecil.Cil.Code.Box:
                    ReturnType = Childnodes[0].ReturnType;
                    break;

                case Mono.Cecil.Cil.Code.Newarr:
                    System.Diagnostics.Trace.Assert(true, "Figure out how to extract the class type");
                    ReturnType = ExtractClassType((Mono.Cecil.MemberReference)Instruction.Operand);
                    break;

                case Mono.Cecil.Cil.Code.Ldelem_Ref:
                    System.Diagnostics.Trace.Assert(true, "Figure out how to extract the class type");
                    ReturnType = (Type)Instruction.Operand;
                    break;

                default:
                    throw new Exception("Unexpected Pushref operation");
                }
                break;
            }
        }
コード例 #27
0
        public IMethod GetMethod(object token)
        {
            IMethod __method = null;

            if (methodCache.TryGetValue(token.GetHashCode(), out __method))
            {
                return(__method);
            }
            Mono.Cecil.ModuleDefinition module = null;
            string          methodname         = null;
            string          typename           = null;
            MethodParamList genlist            = null;
            MethodParamList list = null;

            if (token is Mono.Cecil.MethodReference)
            {
                Mono.Cecil.MethodReference _ref = (token as Mono.Cecil.MethodReference);
                module     = _ref.Module;
                methodname = _ref.Name;
                typename   = _ref.DeclaringType.FullName;
                list       = new MethodParamList(environment, _ref);
                if (_ref.IsGenericInstance)
                {
                    Mono.Cecil.GenericInstanceMethod gmethod = _ref as Mono.Cecil.GenericInstanceMethod;
                    genlist = new MethodParamList(environment, gmethod);
                }
            }
            else if (token is Mono.Cecil.MethodDefinition)
            {
                Mono.Cecil.MethodDefinition _def = token as Mono.Cecil.MethodDefinition;
                module     = _def.Module;
                methodname = _def.Name;
                typename   = _def.DeclaringType.FullName;
                list       = new MethodParamList(environment, _def);
                if (_def.IsGenericInstance)
                {
                    throw new NotImplementedException();
                    //Mono.Cecil.GenericInstanceMethod gmethod = _def as Mono.Cecil.GenericInstanceMethod;
                    //genlist = new MethodParamList(environment, gmethod);
                }
            }
            else
            {
                throw new NotImplementedException();
            }

            var typesys = GetType(typename);

            if (typesys == null)
            {
                typename = typename.Replace("0...", "");
                typesys  = GetType(typename);
            }
            if (typesys == null)
            {
                throw new Exception("type can't find:" + typename);
            }

            IMethod _method = null;

            if (genlist != null)
            {
                _method = typesys.GetMethodT(methodname, genlist, list);
            }
            else
            {
                _method = typesys.GetMethod(methodname, list);
            }
            methodCache[token.GetHashCode()] = _method;
            return(_method);
        }
コード例 #28
0
 public static long GetToken(Mono.Cecil.MethodReference method)
 => (long)((ulong)method.MetadataToken.ToInt32()) << 32 | (
     (uint)((method.Module.Name.GetHashCode() << 5) + method.Module.Name.GetHashCode()) ^
     (uint)method.Module.Assembly.FullName.GetHashCode()
         );
コード例 #29
0
        public static Instruction CallVirtual(Mono.Cecil.MethodReference method)

        {
            return(Instruction.Create(OpCodes.Callvirt, method));
        }