Exemplo n.º 1
0
        private void ConvertMethod(ILMethod from, NeoMethod to)
        {
            this.addr = 0;
            this.addrconv.Clear();

            //插入一个记录深度的代码,再往前的是参数
            // Insert a record depth code, and then forward the parameters
            _insertBeginCode(from, to);

            int skipcount = 0;

            foreach (var src in from.body_Codes.Values)
            {
                if (skipcount > 0)
                {
                    skipcount--;
                }
                else
                {
                    //在return之前加入清理参数代码
                    //Add the cleaning parameter code before return
                    if (src.code == CodeEx.Ret)//before return
                    {
                        _insertEndCode(from, to, src);
                    }
                    try
                    {
                        skipcount = ConvertCode(from, src, to);
                    }
                    catch (Exception err)
                    {
                        throw new Exception("error:" + from.method.FullName + "::" + src, err);
                    }
                }
            }

            ConvertAddrInMethod(to);
        }
Exemplo n.º 2
0
        private int _ConvertStringBuilder(string callname, OpCode src, NeoMethod to)
        {
            if (callname == "<init>")
            {
                _Convert1by1(VM.OpCode.SWAP, null, to);
                _Convert1by1(VM.OpCode.DUP, null, to);

                _ConvertPush(0, null, to);
                _ConvertPush(3, null, to);
                _Convert1by1(VM.OpCode.ROLL, null, to);
                _Convert1by1(VM.OpCode.SETITEM, null, to);
                return(0);
            }
            if (callname == "append")
            {
                _Convert1by1(VM.OpCode.SWAP, null, to);//把对象数组换上来
                _Convert1by1(VM.OpCode.DUP, null, to);
                _ConvertPush(0, null, to);
                _Convert1by1(VM.OpCode.PICKITEM, null, to);

                _ConvertPush(2, null, to);
                _Convert1by1(VM.OpCode.ROLL, null, to);
                _Convert1by1(VM.OpCode.SWAP, null, to);//把对象数组换上来
                _Convert1by1(VM.OpCode.CAT, null, to);

                _ConvertPush(0, null, to);
                _Convert1by1(VM.OpCode.SWAP, null, to);//把对象数组换上来
                _Convert1by1(VM.OpCode.SETITEM, null, to);
                return(0);
            }
            if (callname == "toString")
            {
                _ConvertPush(0, null, to);
                _Convert1by1(VM.OpCode.PICKITEM, null, to);
                return(0);
            }
            return(0);
        }
Exemplo n.º 3
0
        private NeoCode _Insert1(VM.OpCode code, string comment, NeoMethod to, byte[] data = null)
        {
            NeoCode _code     = new NeoCode();
            int     startaddr = addr;

            _code.addr = addr;
            {
                _code.debugcode = comment;
                _code.debugline = 0;
            }

            addr++;

            _code.code = code;

            if (data != null)
            {
                _code.bytes = data;
                addr       += _code.bytes.Length;
            }
            to.body_Codes[startaddr] = _code;
            return(_code);
        }
Exemplo n.º 4
0
        private void _ConvertCastclass(ILMethod method, OpCode src, NeoMethod to)
        {
            var type = src.tokenUnknown as Mono.Cecil.TypeReference;

            try
            {
                var dtype = type.Resolve();
                if (dtype.BaseType.FullName == "System.MulticastDelegate" || dtype.BaseType.FullName == "System.Delegate")
                {
                    foreach (var m in dtype.Methods)
                    {
                        if (m.Name == "Invoke")
                        {
                            to.lastparam = m.Parameters.Count;
                            break;
                        }
                    }
                }
            }
            catch
            {
            }
        }
Exemplo n.º 5
0
        private void _insertBeginCode(ILMethod from, NeoMethod to)
        {
            ////压入深度临时栈
            //Pressed into the depth of the temporary stack
            //_Insert1(Lux.Core.OpCode.DEPTH, "record depth.", to);
            //_Insert1(Lux.Core.OpCode.TOALTSTACK, "", to);

            ////初始化临时槽位位置
            //Initialize the temporary slot location
            //foreach (var src in from.body_Variables)
            //{
            //    to.body_Variables.Add(new ILParam(src.name, src.type));
            //    _InsertPush(0, "body_Variables init", to);
            //}

            //新玩法,用一个数组,应该能减少指令数量
            // New plan, using an array, should reduce the number of instructions
            _InsertPush(from.paramtypes.Count + from.body_Variables.Count, "begincode", to);
            _Insert1(Lux.Core.OpCode.NEWARRAY, "", to);
            _Insert1(Lux.Core.OpCode.TOALTSTACK, "", to);
            //移动参数槽位
            //Move parameter slot
            for (var i = 0; i < from.paramtypes.Count; i++)
            {
                //getarray
                _Insert1(Lux.Core.OpCode.FROMALTSTACK, "set param:" + i, to);
                _Insert1(Lux.Core.OpCode.DUP, null, to);
                _Insert1(Lux.Core.OpCode.TOALTSTACK, null, to);

                _InsertPush(i, "", to); //Array pos

                _InsertPush(2, "", to); //Array item
                _Insert1(Lux.Core.OpCode.ROLL, null, to);

                _Insert1(Lux.Core.OpCode.SETITEM, null, to);
            }
        }
        private int _ConvertIfNonNull(JavaMethod method, OpCode src, NeoMethod to)
        {
            int nm       = method.GetLastCodeAddr(src.addr);//上一指令
            int n        = method.GetNextCodeAddr(src.addr);
            int n2       = method.GetNextCodeAddr(n);
            var codenext = method.body_Codes[n];

            if (nm >= 0 && n >= 0 && n2 >= 0 &&
                method.body_Codes[nm].code == javaloader.NormalizedByteCode.__dup && //上一条是dup指令
                src.arg1 == n2 - src.addr && //刚好跳过throw 指令
                codenext.code == javaloader.NormalizedByteCode.__invokestatic
                )
            {
                var cc   = method.DeclaringType.classfile.constantpool;
                var c    = cc[codenext.arg1] as javaloader.ClassFile.ConstantPoolItemMethodref;
                var name = c.Class + "::" + c.Name;
                if (name == "kotlin.jvm.internal.Intrinsics::throwNpe")
                {//识别到套路
                    var _code = to.body_Codes.Last().Value;
                    //移除上一条指令
                    to.body_Codes.Remove(_code.addr);
                    this.addr = _code.addr;

                    return(1);
                }
            }
            var codenextnext = method.body_Codes[n2];

            _ConvertPush(0, src, to);//和0比较
            _Convert1by1(Pure.VM.OpCode.NUMNOTEQUAL, null, to);
            var code = _Convert1by1(Pure.VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });

            code.needfix = true;
            code.srcaddr = src.addr + src.arg1;
            return(0);
        }
Exemplo n.º 7
0
        private bool TryInsertMethod(NeoModule outModule, Mono.Cecil.MethodDefinition method)
        {
            var oldaddr     = this.addr;
            var oldaddrconv = new Dictionary <int, int>();

            foreach (int k in addrconv.Keys)
            {
                oldaddrconv[k] = addrconv[k];
            }
            var    typename = method.DeclaringType.FullName;
            ILType type;

            if (inModule.mapType.TryGetValue(typename, out type) == false)
            {
                type = new ILType(null, method.DeclaringType);
                inModule.mapType[typename] = type;
            }
            var _method = type.methods[method.FullName];

            try
            {
                NeoMethod nm = new NeoMethod();
                if (method.FullName.Contains(".cctor"))
                {
                    CctorSubVM.Parse(_method, this.outModule);
                    //continue;
                    return(false);
                }
                if (method.IsConstructor)
                {
                    return(false);
                    //continue;
                }
                nm._namespace  = method.DeclaringType.FullName;
                nm.name        = method.FullName;
                nm.displayName = method.Name;
                Mono.Collections.Generic.Collection <Mono.Cecil.CustomAttribute> ca = method.CustomAttributes;
                foreach (var attr in ca)
                {
                    if (attr.AttributeType.Name == "DisplayNameAttribute")
                    {
                        nm.displayName = (string)attr.ConstructorArguments[0].Value;
                    }
                }
                nm.inSmartContract            = method.DeclaringType.BaseType.Name == "SmartContract";
                nm.isPublic                   = method.IsPublic;
                this.methodLink[_method]      = nm;
                outModule.mapMethods[nm.name] = nm;
                ConvertMethod(_method, nm);
                return(true);
            }
            catch
            {
                return(false);
            }
            finally
            {
                this.addr = oldaddr;
                this.addrconv.Clear();
                foreach (int k in oldaddrconv.Keys)
                {
                    addrconv[k] = oldaddrconv[k];
                }
            }
        }
Exemplo n.º 8
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);
        }
Exemplo n.º 9
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);
        }
Exemplo n.º 10
0
        private void _insertSharedStaticVarCode(NeoMethod to)
        {
            if (this.outModule.mapFields.Count > 255)
            {
                throw new Exception("too mush static fields");
            }

            //insert init constvalue part
            byte count = (byte)this.outModule.mapFields.Count;

            if (count > 0)
            {
                _Insert1(VM.OpCode.INITSSLOT, "", to, new byte[] { count }); // INITSSLOT with a u8 len
            }

            foreach (var defvar in this.outModule.staticfieldsWithConstValue)
            {
                if (this.outModule.mapFields.TryGetValue(defvar.Key, out NeoField field))
                {
                    //value
                    #region insertValue
                    //this static var had a default value.
                    var _src = defvar.Value;
                    if (_src is byte[])
                    {
                        var bytesrc = (byte[])_src;
                        _ConvertPush(bytesrc, null, to);
                    }
                    else if (_src is int intsrc)
                    {
                        _ConvertPush(intsrc, null, to);
                    }
                    else if (_src is long longsrc)
                    {
                        _ConvertPush(longsrc, null, to);
                    }
                    else if (_src is bool bsrc)
                    {
                        _ConvertPush(bsrc ? 1 : 0, null, to);
                    }
                    else if (_src is string strsrc)
                    {
                        var bytesrc = Encoding.UTF8.GetBytes(strsrc);
                        _ConvertPush(bytesrc, null, to);
                    }
                    else if (_src is BigInteger bisrc)
                    {
                        byte[] bytes = bisrc.ToByteArray();
                        _ConvertPush(bytes, null, to);
                    }
                    else
                    {
                        //no need to init null
                        _Convert1by1(VM.OpCode.PUSHNULL, null, to);
                    }
                    #endregion

                    if (field.index < 7)
                    {
                        _Insert1(VM.OpCode.STSFLD0 + (byte)field.index, "", to);
                    }
                    else
                    {
                        var fieldIndex = (byte)field.index;
                        _Insert1(VM.OpCode.STSFLD, "", to, new byte[] { fieldIndex });
                    }
                }
            }

            //insert code part
            foreach (var cctor in this.outModule.staticfieldsCctor)
            {
                FillMethod(cctor, to, false);
            }
        }
Exemplo n.º 11
0
        public NeoModule Convert(ILModule _in, ConvOption option = null)
        {
            this.inModule = _in;
            //logger.Log("beginConvert.");
            this.outModule = new NeoModule(this.logger)
            {
                option = option ?? ConvOption.Default
            };
            foreach (var t in _in.mapType)
            {
                if (t.Key.Contains("<"))
                {
                    continue;//系统的,不要
                }
                if (t.Key.Contains("_API_"))
                {
                    continue;                         //api的,不要
                }
                if (t.Key.Contains(".My."))
                {
                    continue;//vb system
                }
                foreach (var m in t.Value.methods)
                {
                    if (m.Value.method == null)
                    {
                        continue;
                    }
                    if (m.Value.method.IsAddOn || m.Value.method.IsRemoveOn)
                    {
                        continue;//event 自动生成的代码,不要
                    }
                    if (m.Value.method.Is_cctor())
                    {
                        CctorSubVM.Parse(m.Value, this.outModule);
                        continue;
                    }
                    if (m.Value.method.Is_ctor())
                    {
                        continue;
                    }
                    NeoMethod nm = new NeoMethod(m.Value);
                    this.methodLink[m.Value]      = nm;
                    outModule.mapMethods[nm.name] = nm;
                }

                foreach (var e in t.Value.fields)
                {
                    if (e.Value.isEvent)
                    {
                        NeoEvent ae = new NeoEvent(e.Value);
                        outModule.mapEvents[ae.name] = ae;
                    }
                    else if (e.Value.field.IsStatic)
                    {
                        var _fieldindex = outModule.mapFields.Count;
                        var field       = new NeoField(e.Key, e.Value.type, _fieldindex);
                        outModule.mapFields[e.Value.field.FullName] = field;
                    }
                }
            }

            var keys = new List <string>(_in.mapType.Keys);

            foreach (var key in keys)
            {
                var value = _in.mapType[key];
                if (key.Contains("<"))
                {
                    continue;//系统的,不要
                }
                if (key.Contains("_API_"))
                {
                    continue;                       //api的,不要
                }
                if (key.Contains(".My."))
                {
                    continue;//vb system
                }
                foreach (var m in value.methods)
                {
                    if (m.Value.method == null)
                    {
                        continue;
                    }
                    if (m.Value.method.Is_cctor())
                    {
                        continue;
                    }
                    if (m.Value.method.IsAddOn || m.Value.method.IsRemoveOn)
                    {
                        continue;//event 自动生成的代码,不要
                    }
                    var nm = this.methodLink[m.Value];

                    //try
                    {
                        nm.returntype = m.Value.returntype;
                        try
                        {
                            var type = m.Value.method.ReturnType.Resolve();
                            foreach (var i in type.Interfaces)
                            {
                                if (i.InterfaceType.Name == "IApiInterface")
                                {
                                    nm.returntype = "IInteropInterface";
                                }
                            }
                        }
                        catch
                        {
                        }

                        foreach (var src in m.Value.paramtypes)
                        {
                            nm.paramtypes.Add(new NeoParam(src.name, src.type));
                        }

                        if (IsAppCall(m.Value.method, out byte[] outcall))
Exemplo n.º 12
0
        public NeoModule Convert(ILModule _in, ConvOption option = null)
        {
            this.inModule  = _in;
            this.outModule = new NeoModule()
            {
                option = option ?? ConvOption.Default
            };
            foreach (var t in _in.mapType)
            {
                if (t.Key.Contains("<"))
                {
                    continue;                        //skip system type
                }
                if (t.Key.Contains("_API_"))
                {
                    continue;                          // skip api
                }
                if (t.Key.Contains(".My."))
                {
                    continue;                         //vb system
                }
                foreach (var m in t.Value.methods)
                {
                    if (m.Value.method == null)
                    {
                        continue;
                    }
                    if (m.Value.method.IsAddOn || m.Value.method.IsRemoveOn)
                    {
                        continue;                                                      // skip the code generated by event
                    }
                    if (m.Value.method.Is_ctor())
                    {
                        continue;
                    }
                    if (m.Value.method.Is_cctor())
                    {
                        //if cctor contains sth can not be as a const value.
                        //  then need 1.record these cctor's code.
                        //            2.insert them to main function
                        CctorSubVM.Parse(m.Value, this.outModule);
                        continue;
                    }

                    NeoMethod nm = new NeoMethod(m.Value);
                    this.methodLink[m.Value]      = nm;
                    outModule.mapMethods[nm.name] = nm;
                }

                foreach (var e in t.Value.fields)
                {
                    if (e.Value.isEvent)
                    {
                        NeoEvent ae = new NeoEvent(e.Value);
                        outModule.mapEvents[ae.name] = ae;
                    }
                    else if (e.Value.field.IsStatic)
                    {
                        var _fieldindex = outModule.mapFields.Count;
                        var field       = new NeoField(e.Key, e.Value.type, _fieldindex);
                        outModule.mapFields[e.Value.field.FullName] = field;
                    }
                }
            }

            var keys = new List <string>(_in.mapType.Keys);

            foreach (var key in keys)
            {
                var value = _in.mapType[key];
                if (key.Contains("<"))
                {
                    continue;                    // skip system typee
                }
                if (key.Contains("_API_"))
                {
                    continue;                        // skip api
                }
                if (key.Contains(".My."))
                {
                    continue;                       //vb system
                }
                foreach (var m in value.methods)
                {
                    if (m.Value.method == null)
                    {
                        continue;
                    }
                    if (m.Value.method.Is_cctor())
                    {
                        continue;
                    }
                    if (m.Value.method.IsAddOn || m.Value.method.IsRemoveOn)
                    {
                        continue;                                                      // skip the code generated by event
                    }
                    var nm = this.methodLink[m.Value];

                    //try
                    {
                        nm.returntype = m.Value.returntype;

                        foreach (var src in m.Value.paramtypes)
                        {
                            nm.paramtypes.Add(new NeoParam(src.name, src.type));
                        }

                        if (IsContractCall(m.Value.method, out _))
                        {
                            continue;
                        }
                        if (IsNonCall(m.Value.method))
                        {
                            continue;
                        }
                        if (IsMixAttribute(m.Value.method, out _, out _))
                        {
                            continue;
                        }

                        if (m.Key.Contains("::Main("))
                        {
                            NeoMethod _m = outModule.mapMethods[m.Key];
                        }
                        this.ConvertMethod(m.Value, nm);
                    }
                }
            }

            if (this.outModule.mapFields.Count > MAX_STATIC_FIELDS_COUNT)
            {
                throw new Exception("too much static fields");
            }
            if (this.outModule.mapFields.Count > 0)
            {
                InsertInitializeMethod();
                logger.Log("Insert _initialize().");
            }

            var attr = outModule.mapMethods.Values.Where(u => u.inSmartContract).Select(u => u.type?.attributes.ToArray()).FirstOrDefault();

            if (attr?.Length > 0)
            {
                outModule.attributes.AddRange(attr);
            }

            var declaringTypes = outModule.mapMethods.Values
                                 .Where(u => u.inSmartContract)
                                 .Select(u => u.method?.method?.DeclaringType)
                                 .Where(u => u != null && !string.IsNullOrEmpty(u.Name))
                                 .Distinct()
                                 .ToArray();

            outModule.Name = declaringTypes.Length == 1 ? declaringTypes[0].Name : Path.GetFileNameWithoutExtension(_in.module.Name);

            this.LinkCode();

            // this.findFirstFunc();// Need to find the first method
            // Assign func addr for each method
            // Then convert the call address

            return(outModule);
        }
Exemplo n.º 13
0
        private int ConvertCode(ILMethod method, OpCode src, NeoMethod to)
        {
            int skipcount = 0;

            switch (src.code)
            {
            case CodeEx.Nop:
                _Convert1by1(VM.OpCode.NOP, src, to);
                break;

            case CodeEx.Ret:
                //return 在外面特殊处理了
                _Insert1(VM.OpCode.RET, null, to);
                break;

            case CodeEx.Pop:
                _Convert1by1(VM.OpCode.DROP, src, to);
                break;

            case CodeEx.Ldnull:
                _ConvertPush(new byte[0], src, to);
                break;

            case CodeEx.Ldc_I4:
            case CodeEx.Ldc_I4_S:
                skipcount = _ConvertPushI4WithConv(method, src.tokenI32, src, to);
                break;

            case CodeEx.Ldc_I4_0:
                _ConvertPush(0, src, to);
                break;

            case CodeEx.Ldc_I4_1:
                _ConvertPush(1, src, to);
                break;

            case CodeEx.Ldc_I4_2:
                _ConvertPush(2, src, to);
                break;

            case CodeEx.Ldc_I4_3:
                _ConvertPush(3, src, to);
                break;

            case CodeEx.Ldc_I4_4:
                _ConvertPush(4, src, to);
                break;

            case CodeEx.Ldc_I4_5:
                _ConvertPush(5, src, to);
                break;

            case CodeEx.Ldc_I4_6:
                _ConvertPush(6, src, to);
                break;

            case CodeEx.Ldc_I4_7:
                _ConvertPush(7, src, to);
                break;

            case CodeEx.Ldc_I4_8:
                _ConvertPush(8, src, to);
                break;

            case CodeEx.Ldc_I4_M1:
                skipcount = _ConvertPushI4WithConv(method, -1, src, to);
                break;

            case CodeEx.Ldc_I8:
                skipcount = _ConvertPushI8WithConv(method, src.tokenI64, src, to);
                break;

            case CodeEx.Ldstr:
                _ConvertPush(Encoding.UTF8.GetBytes(src.tokenStr), src, to);
                break;

            case CodeEx.Stloc_0:
                _ConvertStLoc(method, src, to, 0);
                break;

            case CodeEx.Stloc_1:
                _ConvertStLoc(method, src, to, 1);
                break;

            case CodeEx.Stloc_2:
                _ConvertStLoc(method, src, to, 2);
                break;

            case CodeEx.Stloc_3:
                _ConvertStLoc(method, src, to, 3);
                break;

            case CodeEx.Stloc_S:
                _ConvertStLoc(method, src, to, src.tokenI32);
                break;

            case CodeEx.Ldloc_0:
                _ConvertLdLoc(method, src, to, 0);
                break;

            case CodeEx.Ldloc_1:
                _ConvertLdLoc(method, src, to, 1);
                break;

            case CodeEx.Ldloc_2:
                _ConvertLdLoc(method, src, to, 2);
                break;

            case CodeEx.Ldloc_3:
                _ConvertLdLoc(method, src, to, 3);
                break;

            case CodeEx.Ldloc_S:
                _ConvertLdLoc(method, src, to, src.tokenI32);
                break;

            case CodeEx.Ldarg_0:
                _ConvertLdArg(method, src, to, 0);
                break;

            case CodeEx.Ldarg_1:
                _ConvertLdArg(method, src, to, 1);
                break;

            case CodeEx.Ldarg_2:
                _ConvertLdArg(method, src, to, 2);
                break;

            case CodeEx.Ldarg_3:
                _ConvertLdArg(method, src, to, 3);
                break;

            case CodeEx.Ldarg_S:
            case CodeEx.Ldarg:
            case CodeEx.Ldarga:
            case CodeEx.Ldarga_S:
                _ConvertLdArg(method, src, to, src.tokenI32);
                break;

            case CodeEx.Starg_S:
            case CodeEx.Starg:
                _ConvertStArg(src, to, src.tokenI32);
                break;

            //需要地址轉換的情況
            case CodeEx.Br:
            case CodeEx.Br_S:
            case CodeEx.Leave:
            case CodeEx.Leave_S:
            {
                var code = _Convert1by1(VM.OpCode.JMP, src, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.tokenAddr_Index;
            }

            break;

            case CodeEx.Switch:
            {
                throw new Exception("need neo.VM update.");
                //var addrdata = new byte[src.tokenAddr_Switch.Length * 2 + 2];
                //var shortaddrcount = (UInt16)src.tokenAddr_Switch.Length;
                //var data = BitConverter.GetBytes(shortaddrcount);
                //addrdata[0] = data[0];
                //addrdata[1] = data[1];
                //var code = _Convert1by1(VM.OpCode.SWITCH, src, to, addrdata);
                //code.needfix = true;
                //code.srcaddrswitch = new int[shortaddrcount];
                //for (var i = 0; i < shortaddrcount; i++)
                //{
                //    code.srcaddrswitch[i] = src.tokenAddr_Switch[i];
                //}
            }
            break;

            case CodeEx.Brtrue:
            case CodeEx.Brtrue_S:
            {
                var code = _Convert1by1(VM.OpCode.JMPIF, src, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.tokenAddr_Index;
            }
            break;

            case CodeEx.Brfalse:
            case CodeEx.Brfalse_S:
            {
                var code = _Convert1by1(VM.OpCode.JMPIFNOT, src, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.tokenAddr_Index;
            }
            break;

            case CodeEx.Beq:
            case CodeEx.Beq_S:
            {
                _Convert1by1(VM.OpCode.NUMEQUAL, src, to);
                var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.tokenAddr_Index;
            }
            break;

            case CodeEx.Bne_Un:
            case CodeEx.Bne_Un_S:
            {
                _Convert1by1(VM.OpCode.ABS, src, to);
                _Convert1by1(VM.OpCode.SWAP, null, to);
                _Convert1by1(VM.OpCode.ABS, null, to);
                _Convert1by1(VM.OpCode.SWAP, null, to);
                _Convert1by1(VM.OpCode.NUMNOTEQUAL, null, to);
                var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.tokenAddr_Index;
            }
            break;

            case CodeEx.Blt:
            case CodeEx.Blt_S:
            {
                _Convert1by1(VM.OpCode.LT, src, to);
                var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.tokenAddr_Index;
            }
            break;

            case CodeEx.Blt_Un:
            case CodeEx.Blt_Un_S:
            {
                _Convert1by1(VM.OpCode.ABS, src, to);
                _Convert1by1(VM.OpCode.SWAP, null, to);
                _Convert1by1(VM.OpCode.ABS, null, to);
                _Convert1by1(VM.OpCode.SWAP, null, to);
                _Convert1by1(VM.OpCode.LT, null, to);
                var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.tokenAddr_Index;
            }
            break;

            case CodeEx.Ble:
            case CodeEx.Ble_S:
            {
                _Convert1by1(VM.OpCode.LTE, src, to);
                var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.tokenAddr_Index;
            }
            break;

            case CodeEx.Ble_Un:
            case CodeEx.Ble_Un_S:
            {
                _Convert1by1(VM.OpCode.ABS, src, to);
                _Convert1by1(VM.OpCode.SWAP, null, to);
                _Convert1by1(VM.OpCode.ABS, null, to);
                _Convert1by1(VM.OpCode.SWAP, null, to);
                _Convert1by1(VM.OpCode.LTE, null, to);
                var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.tokenAddr_Index;
            }
            break;

            case CodeEx.Bgt:
            case CodeEx.Bgt_S:
            {
                _Convert1by1(VM.OpCode.GT, src, to);
                var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.tokenAddr_Index;
            }
            break;

            case CodeEx.Bgt_Un:
            case CodeEx.Bgt_Un_S:
            {
                _Convert1by1(VM.OpCode.ABS, src, to);
                _Convert1by1(VM.OpCode.SWAP, null, to);
                _Convert1by1(VM.OpCode.ABS, null, to);
                _Convert1by1(VM.OpCode.SWAP, null, to);
                _Convert1by1(VM.OpCode.GT, null, to);
                var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.tokenAddr_Index;
            }
            break;

            case CodeEx.Bge:
            case CodeEx.Bge_S:
            {
                _Convert1by1(VM.OpCode.GTE, src, to);
                var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.tokenAddr_Index;
            }
            break;

            case CodeEx.Bge_Un:
            case CodeEx.Bge_Un_S:
            {
                _Convert1by1(VM.OpCode.ABS, src, to);
                _Convert1by1(VM.OpCode.SWAP, null, to);
                _Convert1by1(VM.OpCode.ABS, null, to);
                _Convert1by1(VM.OpCode.SWAP, null, to);
                _Convert1by1(VM.OpCode.GTE, null, to);
                var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.tokenAddr_Index;
            }
            break;

            //Stack
            case CodeEx.Dup:
                _Convert1by1(VM.OpCode.DUP, src, to);
                break;

            //Bitwise logic
            case CodeEx.And:
                _Convert1by1(VM.OpCode.AND, src, to);
                break;

            case CodeEx.Or:
                _Convert1by1(VM.OpCode.OR, src, to);
                break;

            case CodeEx.Xor:
                _Convert1by1(VM.OpCode.XOR, src, to);
                break;

            case CodeEx.Not:
                _Convert1by1(VM.OpCode.INVERT, src, to);
                break;

            //math
            case CodeEx.Add:
            case CodeEx.Add_Ovf:
            case CodeEx.Add_Ovf_Un:
                _Convert1by1(VM.OpCode.ADD, src, to);
                break;

            case CodeEx.Sub:
            case CodeEx.Sub_Ovf:
            case CodeEx.Sub_Ovf_Un:
                _Convert1by1(VM.OpCode.SUB, src, to);
                break;

            case CodeEx.Mul:
            case CodeEx.Mul_Ovf:
            case CodeEx.Mul_Ovf_Un:
                _Convert1by1(VM.OpCode.MUL, src, to);
                break;

            case CodeEx.Div:
            case CodeEx.Div_Un:
                _Convert1by1(VM.OpCode.DIV, src, to);
                break;

            case CodeEx.Rem:
            case CodeEx.Rem_Un:
                _Convert1by1(VM.OpCode.MOD, src, to);
                break;

            case CodeEx.Neg:
                _Convert1by1(VM.OpCode.NEGATE, src, to);
                break;

            case CodeEx.Shl:
                _Convert1by1(VM.OpCode.SHL, src, to);
                break;

            case CodeEx.Shr:
            case CodeEx.Shr_Un:
                _Convert1by1(VM.OpCode.SHR, src, to);
                break;

            //logic
            case CodeEx.Clt:
            case CodeEx.Clt_Un:
                _Convert1by1(VM.OpCode.LT, src, to);
                break;

            case CodeEx.Cgt:
            case CodeEx.Cgt_Un:
                _Convert1by1(VM.OpCode.GT, src, to);
                break;

            case CodeEx.Ceq:
                _Convert1by1(VM.OpCode.NUMEQUAL, src, to);
                break;

            //call
            case CodeEx.Call:
            case CodeEx.Callvirt:
                _ConvertCall(src, to);
                break;

            //用上一个参数作为数量,new 一个数组
            case CodeEx.Newarr:
                skipcount = _ConvertNewArr(method, src, to);
                break;


            //array
            //用意为byte[] 取一部分.....
            // en: intent to use byte[] as array.....
            case CodeEx.Ldelem_U1:
            case CodeEx.Ldelem_I1:
            //_ConvertPush(1, src, to);
            //_Convert1by1(VM.OpCode.SUBSTR, null, to);
            //break;
            //now we can use pickitem for byte[]

            case CodeEx.Ldelem_Any:
            case CodeEx.Ldelem_I:
            //case CodeEx.Ldelem_I1:
            case CodeEx.Ldelem_I2:
            case CodeEx.Ldelem_I4:
            case CodeEx.Ldelem_I8:
            case CodeEx.Ldelem_R4:
            case CodeEx.Ldelem_R8:
            case CodeEx.Ldelem_Ref:
            case CodeEx.Ldelem_U2:
            case CodeEx.Ldelem_U4:
                _Convert1by1(VM.OpCode.PICKITEM, src, to);
                break;

            case CodeEx.Ldlen:
                _Convert1by1(VM.OpCode.ARRAYSIZE, src, to);
                break;

            case CodeEx.Stelem_I1:
            {
                // WILL TRACE VARIABLE ORIGIN "Z" IN ALTSTACK!
                // EXPECTS:  source[index] = b; // index and b must be variables! constants will fail!

                /*
                 * 9 6a DUPFROMALTSTACK
                 * 8 5Z PUSHZ
                 * 7 c3 PICKITEM
                 * 6 6a DUPFROMALTSTACK
                 * 5 5Y PUSHY
                 * 4 c3 PICKITEM
                 * 3 6a DUPFROMALTSTACK
                 * 2 5X PUSHX
                 * 1 c3 PICKITEM
                 */

                if ((to.body_Codes[addr - 1].code == VM.OpCode.PICKITEM) &&
                    (to.body_Codes[addr - 4].code == VM.OpCode.PICKITEM) &&
                    (to.body_Codes[addr - 7].code == VM.OpCode.PICKITEM) &&
                    (to.body_Codes[addr - 3].code == VM.OpCode.DUPFROMALTSTACK) &&
                    (to.body_Codes[addr - 6].code == VM.OpCode.DUPFROMALTSTACK) &&
                    (to.body_Codes[addr - 9].code == VM.OpCode.DUPFROMALTSTACK) &&
                    ((to.body_Codes[addr - 2].code >= VM.OpCode.PUSH0) && (to.body_Codes[addr - 2].code <= VM.OpCode.PUSH16)) &&
                    ((to.body_Codes[addr - 5].code >= VM.OpCode.PUSH0) && (to.body_Codes[addr - 5].code <= VM.OpCode.PUSH16)) &&
                    ((to.body_Codes[addr - 8].code >= VM.OpCode.PUSH0) && (to.body_Codes[addr - 8].code <= VM.OpCode.PUSH16))
                    )
                {
                    // WILL REQUIRE TO PROCESS INFORMATION AND STORE IT AGAIN ON ALTSTACK CORRECT POSITION
                    VM.OpCode PushZ = to.body_Codes[addr - 8].code;

                    _Convert1by1(VM.OpCode.PUSH2, null, to);
                    _Convert1by1(VM.OpCode.PICK, null, to);
                    _Convert1by1(VM.OpCode.PUSH2, null, to);
                    _Convert1by1(VM.OpCode.PICK, null, to);
                    _Convert1by1(VM.OpCode.LEFT, null, to);
                    _Convert1by1(VM.OpCode.SWAP, null, to);
                    _Convert1by1(VM.OpCode.CAT, null, to);
                    _Convert1by1(VM.OpCode.ROT, null, to);
                    _Convert1by1(VM.OpCode.ROT, null, to);
                    _Convert1by1(VM.OpCode.OVER, null, to);
                    _Convert1by1(VM.OpCode.ARRAYSIZE, null, to);
                    _Convert1by1(VM.OpCode.DEC, null, to);
                    _Convert1by1(VM.OpCode.SWAP, null, to);
                    _Convert1by1(VM.OpCode.SUB, null, to);
                    _Convert1by1(VM.OpCode.RIGHT, null, to);
                    _Convert1by1(VM.OpCode.CAT, null, to);

                    // FINAL RESULT MUST GO BACK TO POSITION Z ON ALTSTACK

                    // FINAL STACK:
                    // 4 get array (dupfromaltstack)
                    // 3 PushZ
                    // 2 result
                    // 1 setitem

                    _Convert1by1(VM.OpCode.DUPFROMALTSTACK, null, to);            // stack: [ array , result , ... ]
                    _Convert1by1(PushZ, null, to);                                // stack: [ pushz, array , result , ... ]
                    _Convert1by1(VM.OpCode.ROT, null, to);                        // stack: [ result, pushz, array , ... ]
                    _Convert1by1(VM.OpCode.SETITEM, null, to);                    // stack: [ result, pushz, array , ... ]
                }
                else
                {
                    throw new Exception("neomachine currently supports only variable indexed bytearray attribution, example: byte[] source; int index = 0; byte b = 1; source[index] = b;");
                }
            }           // end case
            break;

            case CodeEx.Stelem_Any:
            case CodeEx.Stelem_I:
            //case CodeEx.Stelem_I1:
            case CodeEx.Stelem_I2:
            case CodeEx.Stelem_I4:
            case CodeEx.Stelem_I8:
            case CodeEx.Stelem_R4:
            case CodeEx.Stelem_R8:
            case CodeEx.Stelem_Ref:
                _Convert1by1(VM.OpCode.SETITEM, src, to);
                break;

            case CodeEx.Isinst:    //支持处理as 表达式
                break;

            case CodeEx.Castclass:
                _ConvertCastclass(method, src, to);
                break;

            case CodeEx.Box:
            case CodeEx.Unbox:
            case CodeEx.Unbox_Any:
            case CodeEx.Break:
            //也有可能以后利用这个断点调试
            case CodeEx.Conv_I:
            case CodeEx.Conv_I1:
            case CodeEx.Conv_I2:
            case CodeEx.Conv_I4:
            case CodeEx.Conv_I8:
            case CodeEx.Conv_Ovf_I:
            case CodeEx.Conv_Ovf_I_Un:
            case CodeEx.Conv_Ovf_I1:
            case CodeEx.Conv_Ovf_I1_Un:
            case CodeEx.Conv_Ovf_I2:
            case CodeEx.Conv_Ovf_I2_Un:
            case CodeEx.Conv_Ovf_I4:
            case CodeEx.Conv_Ovf_I4_Un:
            case CodeEx.Conv_Ovf_I8:
            case CodeEx.Conv_Ovf_I8_Un:
            case CodeEx.Conv_Ovf_U:
            case CodeEx.Conv_Ovf_U_Un:
            case CodeEx.Conv_Ovf_U1:
            case CodeEx.Conv_Ovf_U1_Un:
            case CodeEx.Conv_Ovf_U2:
            case CodeEx.Conv_Ovf_U2_Un:
            case CodeEx.Conv_Ovf_U4:
            case CodeEx.Conv_Ovf_U4_Un:
            case CodeEx.Conv_Ovf_U8:
            case CodeEx.Conv_Ovf_U8_Un:
            case CodeEx.Conv_U:
            case CodeEx.Conv_U1:
            case CodeEx.Conv_U2:
            case CodeEx.Conv_U4:
            case CodeEx.Conv_U8:
                break;

            ///////////////////////////////////////////////
            //以下因为支持结构体而出现
            //加载一个引用,这里改为加载一个pos值
            case CodeEx.Ldloca:
            case CodeEx.Ldloca_S:
                _ConvertLdLocA(method, src, to, src.tokenI32);
                break;

            case CodeEx.Initobj:
                _ConvertInitObj(src, to);
                break;

            case CodeEx.Newobj:
                _ConvertNewObj(src, to);
                break;

            case CodeEx.Stfld:
                _ConvertStfld(method, src, to);
                break;

            case CodeEx.Ldfld:
                _ConvertLdfld(src, to);
                break;

            case CodeEx.Ldsfld:

            {
                _Convert1by1(VM.OpCode.NOP, src, to);
                var d = src.tokenUnknown as Mono.Cecil.FieldDefinition;
                //如果是readonly,可以pull个常量上来的
                if (
                    ((d.Attributes & Mono.Cecil.FieldAttributes.InitOnly) > 0) &&
                    ((d.Attributes & Mono.Cecil.FieldAttributes.Static) > 0)
                    )
                {
                    var fname = d.DeclaringType.FullName + "::" + d.Name;
                    var _src  = outModule.staticfields[fname];
                    if (_src is byte[])
                    {
                        var bytesrc = (byte[])_src;
                        _ConvertPush(bytesrc, src, to);
                    }
                    else if (_src is int)
                    {
                        var intsrc = (int)_src;
                        _ConvertPush(intsrc, src, to);
                    }
                    else if (_src is long)
                    {
                        var intsrc = (long)_src;
                        _ConvertPush(intsrc, src, to);
                    }
                    else if (_src is Boolean)
                    {
                        var bsrc = (Boolean)_src;
                        _ConvertPush(bsrc ? 1 : 0, src, to);
                    }
                    else if (_src is string)
                    {
                        var bytesrc = System.Text.Encoding.UTF8.GetBytes((string)_src);
                        _ConvertPush(bytesrc, src, to);
                    }
                    else if (_src is BigInteger)
                    {
                        byte[] bytes = ((BigInteger)_src).ToByteArray();
                        _ConvertPush(bytes, src, to);
                    }
                    else
                    {
                        throw new Exception("not support type Ldsfld\r\n   in: " + to.name + "\r\n");
                    }
                    break;
                }


                //如果是调用event导致的这个代码,只找出他的名字
                if (d.DeclaringType.HasEvents)
                {
                    foreach (var ev in d.DeclaringType.Events)
                    {
                        if (ev.Name == d.Name && ev.EventType.FullName == d.FieldType.FullName)
                        {
                            Mono.Collections.Generic.Collection <Mono.Cecil.CustomAttribute> ca = ev.CustomAttributes;
                            to.lastsfieldname = d.Name;
                            foreach (var attr in ca)
                            {
                                if (attr.AttributeType.Name == "DisplayNameAttribute")
                                {
                                    to.lastsfieldname = (string)attr.ConstructorArguments[0].Value;
                                }
                            }
                            break;
                        }
                    }
                }
                else
                {        //如果走到这里,是一个静态成员,但是没有添加readonly 表示
                    throw new Exception("Just allow defined a static variable with readonly." + d.FullName);
                }
            }
            break;

            case CodeEx.Throw:
            {
                _Convert1by1(VM.OpCode.THROW, src, to);        //throw 会让vm 挂起
                //不需要再插入return
                //_Insert1(VM.OpCode.RET, "", to);
            }
            break;

            default:
#if WITHPDB
                logger.Log("unsupported instruction " + src.code + "\r\n   in: " + to.name + "\r\n");
                break;
#else
                throw new Exception("unsupported instruction " + src.code + "\r\n   in: " + to.name + "\r\n");
#endif
            }

            return(skipcount);
        }
Exemplo n.º 14
0
        private int _ConvertNewArr(ILMethod method, OpCode src, NeoMethod to)
        {
            var type = src.tokenType;

            if (type != "System.Byte")
            {
                _Convert1by1(VM.OpCode.NEWARRAY, src, to);
                int n  = method.GetNextCodeAddr(src.addr);
                int n2 = method.GetNextCodeAddr(n);
                int n3 = method.GetNextCodeAddr(n2);
                if (n >= 0 && n2 >= 0 && n3 >= 0 && method.body_Codes[n].code == CodeEx.Dup && method.body_Codes[n2].code == CodeEx.Ldtoken && method.body_Codes[n3].code == CodeEx.Call)
                {//這是在初始化數組
                    var data = method.body_Codes[n2].tokenUnknown as byte[];
                    if (type == "System.Char")
                    {
                        for (var i = 0; i < data.Length; i += 2)
                        {
                            char info = BitConverter.ToChar(data, i);
                            _Convert1by1(VM.OpCode.DUP, null, to);
                            _ConvertPush(i / 2, null, to);
                            _ConvertPush(info, null, to);
                            _Convert1by1(VM.OpCode.SETITEM, null, to);
                        }
                        return(3);
                    }
                    throw new Exception("not support this type's init array.");
                }
                return(0);
                //this.logger.Log("_ConvertNewArr::not support type " + type + " for array.");
            }
            else
            {
                var code = to.body_Codes.Last().Value;
                //we need a number
                if (code.code > VM.OpCode.PUSH16)
                {
                    throw new Exception("_ConvertNewArr::not support var lens for new byte[?].");
                }
                var number = getNumber(code);

                //移除上一条指令
                to.body_Codes.Remove(code.addr);
                this.addr = code.addr;

                //new array 指令處理有問題,這個addr 已經包括了data
                //if (code.bytes != null)
                //    this.addr -= code.bytes.Length;

                int n  = method.GetNextCodeAddr(src.addr);
                int n2 = method.GetNextCodeAddr(n);
                int n3 = method.GetNextCodeAddr(n2);
                int n4 = method.GetNextCodeAddr(n3);
                if (n >= 0 && n2 >= 0 && n3 >= 0 && method.body_Codes[n].code == CodeEx.Dup && method.body_Codes[n2].code == CodeEx.Ldtoken && method.body_Codes[n3].code == CodeEx.Call)
                {//這是在初始化數組
                    var data = method.body_Codes[n2].tokenUnknown as byte[];
                    this._ConvertPush(data, src, to);

                    return(3);
                }
                else
                {
                    var outbyte = new byte[number];
                    var skip    = 0;
                    int start   = n;
                    System.Collections.Generic.Stack <int> stack = new System.Collections.Generic.Stack <int>();
                    var _code = method.body_Codes[start];
                    if (_code.code == CodeEx.Dup)//生成的setlem代码用dup
                    {
                        while (true)
                        {
                            int start2 = method.GetNextCodeAddr(start);
                            int start3 = method.GetNextCodeAddr(start2);
                            int start4 = method.GetNextCodeAddr(start3);
                            if (start < 0 || start2 < 0 || start3 < 0 || start4 < 0)
                            {
                                break;
                            }

                            _code = method.body_Codes[start];
                            var _code2 = method.body_Codes[start2];
                            var _code3 = method.body_Codes[start3];
                            var _code4 = method.body_Codes[start4];
                            if (_code.code != CodeEx.Dup || (_code4.code != CodeEx.Stelem_I1 && _code4.code != CodeEx.Stelem_I))
                            {
                                break;
                            }
                            else
                            {
                                var pos   = _code2.tokenI32;
                                var value = _code3.tokenI32;
                                outbyte[pos] = (byte)value;

                                skip += 4;
                                start = method.GetNextCodeAddr(start4);
                            }
                        }
                    }
                    else if ((_code.code == CodeEx.Stloc || _code.code == CodeEx.Stloc_0 || _code.code == CodeEx.Stloc_1 || _code.code == CodeEx.Stloc_2 || _code.code == CodeEx.Stloc_3 || _code.code == CodeEx.Stloc_S))
                    {
                        skip++;
                        start = method.GetNextCodeAddr(start);
                        _code = method.body_Codes[start];
                        bool bLdLoc = (_code.code == CodeEx.Ldloc || _code.code == CodeEx.Ldloc_0 || _code.code == CodeEx.Ldloc_1 || _code.code == CodeEx.Ldloc_2 || _code.code == CodeEx.Ldloc_3 || _code.code == CodeEx.Ldloc_S);
                        if (bLdLoc == false)//说明根本没有初始化的意思
                        {
                            this._ConvertPush(outbyte, src, to);
                            return(0);
                        }
                        while (true)
                        {
                            int start2 = method.GetNextCodeAddr(start);
                            int start3 = method.GetNextCodeAddr(start2);
                            int start4 = method.GetNextCodeAddr(start3);
                            if (start < 0 || start2 < 0 || start3 < 0 || start4 < 0)
                            {
                                break;
                            }
                            _code = method.body_Codes[start];
                            var _code2 = method.body_Codes[start2];
                            var _code3 = method.body_Codes[start3];
                            var _code4 = method.body_Codes[start4];
                            bLdLoc = (_code.code == CodeEx.Ldloc || _code.code == CodeEx.Ldloc_0 || _code.code == CodeEx.Ldloc_1 || _code.code == CodeEx.Ldloc_2 || _code.code == CodeEx.Ldloc_3 || _code.code == CodeEx.Ldloc_S);
                            bool bStelem = (_code4.code == CodeEx.Stelem_I1 || _code4.code == CodeEx.Stelem_I);
                            if (bLdLoc && bStelem)
                            {
                                var pos   = _code2.tokenI32;
                                var value = _code3.tokenI32;
                                outbyte[pos] = (byte)value;

                                skip += 4;
                                start = method.GetNextCodeAddr(start4);
                            }
                            else if (bLdLoc && !bStelem)
                            {
                                //走到这里说明不是预测的数组初始化,少处理了一种情况
                                this._ConvertPush(outbyte, src, to);
                                //就有两种情况
                                if (skip == 1)
                                {
                                    return(0);//没有初始化,那么第一个stloc 是不能跳过的
                                }
                                else
                                {
                                    break;
                                }
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                    //有时c#也会用填数值的方式初始化,对于byte这会出错

                    this._ConvertPush(outbyte, src, to);
                    return(skip);
                }
            }



            return(0);
        }
        private int _ConvertNewArray(JavaMethod method, OpCode src, NeoMethod to)
        {
            int skipcount = 0;

            if (src.arg1 != 8)
            {
                //this.logger.Log("_ConvertNewArray::not support type " + src.arg1 + " for array.");
                _Convert1by1(Pure.VM.OpCode.NEWARRAY, src, to);
                return(0);
            }
            //bytearray
            var code = to.body_Codes.Last().Value;

            //we need a number
            if (code.code > Pure.VM.OpCode.PUSH16)
            {
                throw new Exception("_ConvertNewArr::not support var lens for new byte[?].");
            }
            var number = getNumber(code);

            //移除上一条指令
            to.body_Codes.Remove(code.addr);
            this.addr = code.addr;

            OpCode next     = src;
            int    dupcount = 0;
            int    pcount   = 0;

            int[]  buf    = new int[] { 0, 0, 0 };
            byte[] outbuf = new byte[number];
            do
            {
                int n = method.GetNextCodeAddr(next.addr);
                next = method.body_Codes[n];
                if (next.code == javaloader.NormalizedByteCode.__invokestatic)
                {
                    var i        = method.DeclaringType.classfile.constantpool[next.arg1] as javaloader.ClassFile.ConstantPoolItemMethodref;
                    var callname = i.Class + "::" + i.Name;
                    if (callname == "java.lang.Integer::valueOf")
                    {
                        //nothing
                        skipcount++;
                    }
                    else
                    {
                        throw new Exception("can not parse this new array code chain." + next.code);
                    }
                }
                else if (next.code == javaloader.NormalizedByteCode.__invokevirtual)
                {
                    var i        = method.DeclaringType.classfile.constantpool[next.arg1] as javaloader.ClassFile.ConstantPoolItemMethodref;
                    var callname = i.Class + "::" + i.Name;
                    if (callname == "java.lang.Byte::byteValue")
                    {
                        skipcount++;
                    }
                    else
                    {
                        throw new Exception("can not parse this new array code chain." + next.code);
                    }
                }
                else if (next.code == javaloader.NormalizedByteCode.__checkcast)
                {
                    //nothing
                    skipcount++;
                }
                else if (next.code == javaloader.NormalizedByteCode.__dup)
                {
                    dupcount++;
                    skipcount++;
                }
                else if (next.code == javaloader.NormalizedByteCode.__iconst)
                {
                    buf[pcount] = next.arg1;
                    pcount++;
                    skipcount++;
                }
                else if (next.code == javaloader.NormalizedByteCode.__bastore)
                {
                    dupcount--;
                    var v = (byte)buf[pcount - 1];
                    var i = buf[pcount - 2];
                    //while (outbuf.Count <= i)
                    //    outbuf.Add(0);
                    outbuf[i] = v;
                    pcount   -= 2;
                    skipcount++;
                }
                else if (next.code == javaloader.NormalizedByteCode.__astore)
                {
                    _ConvertPush(outbuf.ToArray(), src, to);
                    return(skipcount);
                }
                else
                {
                    throw new Exception("can not parse this new array code chain.");
                }
            }while (next != null);

            return(0);
        }
Exemplo n.º 16
0
        private int _ConvertNewArr(ILMethod method, OpCode src, NeoMethod to)
        {
            var type = src.tokenType;

            if (type != "System.Byte")
            {
                _Convert1by1(VM.OpCode.NEWARRAY, src, to);
                int n  = method.GetNextCodeAddr(src.addr);
                int n2 = method.GetNextCodeAddr(n);
                int n3 = method.GetNextCodeAddr(n2);
                if (n >= 0 && n2 >= 0 && n3 >= 0 && method.body_Codes[n].code == CodeEx.Dup && method.body_Codes[n2].code == CodeEx.Ldtoken && method.body_Codes[n3].code == CodeEx.Call)
                {//這是在初始化數組
                    var data = method.body_Codes[n2].tokenUnknown as byte[];
                    if (type == "System.Char")
                    {
                        for (var i = 0; i < data.Length; i += 2)
                        {
                            char info = BitConverter.ToChar(data, i);
                            _Convert1by1(VM.OpCode.DUP, null, to);
                            _ConvertPush(i / 2, null, to);
                            _ConvertPush(info, null, to);
                            _Convert1by1(VM.OpCode.SETITEM, null, to);
                        }
                        return(3);
                    }
                    throw new Exception("not support this type's init array.");
                }
                return(0);
                //this.logger.Log("_ConvertNewArr::not support type " + type + " for array.");
            }
            else
            {
                var code = to.body_Codes.Last().Value;
                //we need a number
                if (code.code > VM.OpCode.PUSH16)
                {
                    throw new Exception("_ConvertNewArr::not support var lens for new byte[?].");
                }
                var number = getNumber(code);

                //移除上一条指令
                to.body_Codes.Remove(code.addr);
                this.addr = code.addr;
                if (code.bytes != null)
                {
                    this.addr -= code.bytes.Length;
                }

                int n  = method.GetNextCodeAddr(src.addr);
                int n2 = method.GetNextCodeAddr(n);
                int n3 = method.GetNextCodeAddr(n2);
                int n4 = method.GetNextCodeAddr(n3);
                if (n >= 0 && n2 >= 0 && n3 >= 0 && method.body_Codes[n].code == CodeEx.Dup && method.body_Codes[n2].code == CodeEx.Ldtoken && method.body_Codes[n3].code == CodeEx.Call)
                {//這是在初始化數組
                    var data = method.body_Codes[n2].tokenUnknown as byte[];
                    this._ConvertPush(data, src, to);

                    return(3);
                }
                else
                {
                    var outbyte = new byte[number];
                    var skip    = 0;
                    int start   = n;
                    System.Collections.Generic.Stack <int> stack = new System.Collections.Generic.Stack <int>();
                    //有时c#也会用填数值的方式初始化,对于byte这会出错
                    while (true)
                    {
                        int start2 = method.GetNextCodeAddr(start);
                        int start3 = method.GetNextCodeAddr(start2);
                        int start4 = method.GetNextCodeAddr(start3);
                        if (start < 0 || start2 < 0 || start3 < 0 || start4 < 0)
                        {
                            break;
                        }
                        var _code  = method.body_Codes[start];
                        var _code2 = method.body_Codes[start2];
                        var _code3 = method.body_Codes[start3];
                        var _code4 = method.body_Codes[start4];
                        if (_code.code != CodeEx.Dup || (_code4.code != CodeEx.Stelem_I1 && _code4.code != CodeEx.Stelem_I))
                        {
                            break;
                        }
                        var pos   = _code2.tokenI32;
                        var value = _code3.tokenI32;
                        outbyte[pos] = (byte)value;

                        skip += 4;
                        start = method.GetNextCodeAddr(start4);
                    }
                    this._ConvertPush(outbyte, src, to);
                    return(skip);
                }
            }



            return(0);
        }
Exemplo n.º 17
0
        private void InsertSharedStaticVarCode(NeoMethod to)
        {
            //insert init constvalue part
            byte count = (byte)this.outModule.mapFields.Count;

            if (count > 0)
            {
                Insert1(VM.OpCode.INITSSLOT, "", to, new byte[] { count }); // INITSSLOT with a u8 len
            }

            foreach (var defvar in this.outModule.staticfieldsWithConstValue)
            {
                if (this.outModule.mapFields.TryGetValue(defvar.Key, out NeoField field))
                {
                    //value
                    #region insertValue
                    //this static var had a default value.
                    var _src = defvar.Value;
                    if (_src is byte[])
                    {
                        ConvertPushDataArray((byte[])_src, null, to);
                    }
                    else if (_src is int intsrc)
                    {
                        ConvertPushNumber(intsrc, null, to);
                    }
                    else if (_src is long longsrc)
                    {
                        ConvertPushNumber(longsrc, null, to);
                    }
                    else if (_src is bool bsrc)
                    {
                        ConvertPushBoolean(bsrc, null, to);
                    }
                    else if (_src is string strsrc)
                    {
                        ConvertPushString(strsrc, null, to);
                    }
                    else if (_src is BigInteger bisrc)
                    {
                        ConvertPushNumber(bisrc, null, to);
                    }
                    else if (_src is string[] strArray)
                    {
                        ConvertPushStringArray(strArray, null, to);
                    }
                    else
                    {
                        //no need to init null
                        Convert1by1(VM.OpCode.PUSHNULL, null, to);
                    }
                    #endregion

                    if (field.index < 7)
                    {
                        Insert1(VM.OpCode.STSFLD0 + (byte)field.index, "", to);
                    }
                    else
                    {
                        var fieldIndex = (byte)field.index;
                        Insert1(VM.OpCode.STSFLD, "", to, new byte[] { fieldIndex });
                    }
                }
            }

            //insert code part
            foreach (var cctor in this.outModule.staticfieldsCctor)
            {
                FillMethod(cctor, to, false);
            }
        }
Exemplo n.º 18
0
        private void ConvertPushString(string str, OpCode src, NeoMethod to)
        {
            var data = Encoding.UTF8.GetBytes(str);

            ConvertPushDataArray(data, src, to);
        }
Exemplo n.º 19
0
        public NeoModule Convert(ILModule _in, ConvOption option = null)
        {
            this.inModule = _in;
            //logger.Log("beginConvert.");
            this.outModule = new NeoModule(this.logger)
            {
                option = option ?? ConvOption.Default
            };
            foreach (var t in _in.mapType)
            {
                if (t.Key.Contains("<"))
                {
                    continue;//系统的,不要
                }
                if (t.Key.Contains("_API_"))
                {
                    continue;                         //api的,不要
                }
                if (t.Key.Contains(".My."))
                {
                    continue;//vb system
                }
                foreach (var m in t.Value.methods)
                {
                    if (m.Value.method == null)
                    {
                        continue;
                    }
                    if (m.Value.method.IsAddOn || m.Value.method.IsRemoveOn)
                    {
                        continue;//event 自动生成的代码,不要
                    }
                    NeoMethod nm = new NeoMethod();
                    if (m.Key.Contains(".cctor"))
                    {
                        CctorSubVM.Parse(m.Value, this.outModule);
                        continue;
                    }
                    if (m.Value.method.IsConstructor)
                    {
                        continue;
                    }
                    nm._namespace  = m.Value.method.DeclaringType.FullName;
                    nm.name        = m.Value.method.FullName;
                    nm.displayName = m.Value.method.Name;

                    Mono.Collections.Generic.Collection <Mono.Cecil.CustomAttribute> ca = m.Value.method.CustomAttributes;
                    foreach (var attr in ca)
                    {
                        if (attr.AttributeType.Name == "DisplayNameAttribute")
                        {
                            nm.displayName = (string)attr.ConstructorArguments[0].Value;
                        }
                    }
                    nm.inSmartContract            = m.Value.method.DeclaringType.BaseType.Name == "SmartContract";
                    nm.isPublic                   = m.Value.method.IsPublic;
                    this.methodLink[m.Value]      = nm;
                    outModule.mapMethods[nm.name] = nm;
                }
                foreach (var e in t.Value.fields)
                {
                    if (e.Value.isEvent)
                    {
                        NeoEvent ae = new NeoEvent
                        {
                            _namespace  = e.Value.field.DeclaringType.FullName,
                            name        = e.Value.field.DeclaringType.FullName + "::" + e.Key,
                            displayName = e.Value.displayName,
                            returntype  = e.Value.returntype,
                            paramtypes  = e.Value.paramtypes
                        };
                        outModule.mapEvents[ae.name] = ae;
                    }
                    else if (e.Value.field.IsStatic)
                    {
                        var _fieldindex = outModule.mapFields.Count;
                        var field       = new NeoField(e.Key, e.Value.type, _fieldindex);
                        outModule.mapFields[e.Value.field.FullName] = field;
                    }
                }
            }

            var keys = new List <string>(_in.mapType.Keys);

            foreach (var key in keys)
            {
                var value = _in.mapType[key];
                if (key.Contains("<"))
                {
                    continue;//系统的,不要
                }
                if (key.Contains("_API_"))
                {
                    continue;                       //api的,不要
                }
                if (key.Contains(".My."))
                {
                    continue;//vb system
                }
                foreach (var m in value.methods)
                {
                    if (m.Value.method == null)
                    {
                        continue;
                    }
                    if (m.Key.Contains(".cctor"))
                    {
                        continue;
                    }
                    if (m.Value.method.IsAddOn || m.Value.method.IsRemoveOn)
                    {
                        continue;//event 自动生成的代码,不要
                    }
                    var nm = this.methodLink[m.Value];


                    //try
                    {
                        nm.returntype = m.Value.returntype;
                        try
                        {
                            var type = m.Value.method.ReturnType.Resolve();
                            foreach (var i in type.Interfaces)
                            {
                                if (i.InterfaceType.Name == "IApiInterface")
                                {
                                    nm.returntype = "IInteropInterface";
                                }
                            }
                        }
                        catch
                        {
                        }

                        foreach (var src in m.Value.paramtypes)
                        {
                            nm.paramtypes.Add(new NeoParam(src.name, src.type));
                        }

                        if (IsAppCall(m.Value.method, out byte[] outcall))
Exemplo n.º 20
0
        public NeoModule Convert(ILModule _in)
        {
            //logger.Log("beginConvert.");
            this.outModule = new NeoModule(this.logger);
            foreach (var t in _in.mapType)
            {
                if (t.Key.Contains("<"))
                {
                    continue;//系统的,不要 system, no
                }
                if (t.Key.Contains("_API_"))
                {
                    continue;                         //api的,不要 api, do not
                }
                if (t.Key.Contains(".My."))
                {
                    continue;//vb system
                }
                foreach (var m in t.Value.methods)
                {
                    if (m.Value.method == null)
                    {
                        continue;
                    }
                    if (m.Value.method.IsAddOn || m.Value.method.IsRemoveOn)
                    {
                        continue;//event 自动生成的代码,不要 Auto - generated code, do not
                    }
                    NeoMethod nm = new NeoMethod();
                    if (m.Key.Contains(".cctor"))
                    {
                        CctorSubVM.Parse(m.Value, this.outModule);
                        continue;
                    }
                    if (m.Value.method.IsConstructor)
                    {
                        continue;
                    }
                    nm._namespace  = m.Value.method.DeclaringType.FullName;
                    nm.name        = m.Value.method.FullName;
                    nm.displayName = m.Value.method.Name;

                    Mono.Collections.Generic.Collection <Mono.Cecil.CustomAttribute> ca = m.Value.method.CustomAttributes;
                    foreach (var attr in ca)
                    {
                        if (attr.AttributeType.Name == "DisplayNameAttribute")
                        {
                            nm.displayName = (string)attr.ConstructorArguments[0].Value;
                        }
                    }
                    nm.inSmartContract            = m.Value.method.DeclaringType.BaseType.Name == "SmartContract";
                    nm.isPublic                   = m.Value.method.IsPublic;
                    this.methodLink[m.Value]      = nm;
                    outModule.mapMethods[nm.name] = nm;
                }
                foreach (var e in t.Value.fields)
                {
                    if (e.Value.isEvent)
                    {
                        NeoEvent ae = new NeoEvent();
                        ae._namespace  = e.Value.field.DeclaringType.FullName;
                        ae.name        = ae._namespace + "::" + e.Key;
                        ae.displayName = e.Value.displayName;
                        ae.returntype  = e.Value.returntype;
                        ae.paramtypes  = e.Value.paramtypes;
                        outModule.mapEvents[ae.name] = ae;
                    }
                }
            }


            foreach (var t in _in.mapType)
            {
                if (t.Key.Contains("<"))
                {
                    continue;//系统的,不要 Systematic, no
                }
                if (t.Key.Contains("_API_"))
                {
                    continue;                         //api的,不要 api, do not
                }
                if (t.Key.Contains(".My."))
                {
                    continue;//vb system
                }
                foreach (var m in t.Value.methods)
                {
                    if (m.Value.method == null)
                    {
                        continue;
                    }
                    if (m.Key.Contains(".cctor"))
                    {
                        continue;
                    }
                    if (m.Value.method.IsAddOn || m.Value.method.IsRemoveOn)
                    {
                        continue;//event 自动生成的代码,不要 Auto-generated code, do not
                    }
                    var nm = this.methodLink[m.Value];


                    //try
                    {
                        nm.returntype = m.Value.returntype;
                        try
                        {
                            var type = m.Value.method.ReturnType.Resolve();
                            foreach (var i in type.Interfaces)
                            {
                                if (i.Name == "IApiInterface")
                                {
                                    nm.returntype = "IInteropInterface";
                                }
                            }
                        }
                        catch (Exception)
                        {
                        }

                        foreach (var src in m.Value.paramtypes)
                        {
                            nm.paramtypes.Add(new NeoParam(src.name, src.type));
                        }

                        byte[] outcall; string name;
                        if (IsAppCall(m.Value.method, out outcall))
                        {
                            continue;
                        }
                        if (IsNonCall(m.Value.method))
                        {
                            continue;
                        }
                        if (IsOpCall(m.Value.method, out name))
                        {
                            continue;
                        }
                        if (IsSysCall(m.Value.method, out name))
                        {
                            continue;
                        }

                        this.ConvertMethod(m.Value, nm);
                    }
                    //catch (Exception err)
                    //{
                    //    logger.Log("error:" + err.Message);
                    //}
                }
            }
            //转换完了,做个link,全部拼到一起 Conversion finished, be a link, all together
            string mainmethod = "";

            foreach (var key in outModule.mapMethods.Keys)
            {
                if (key.Contains("::Main("))
                {
                    NeoMethod m = outModule.mapMethods[key];
                    if (m.inSmartContract)
                    {
                        foreach (var l in this.methodLink)
                        {
                            if (l.Value == m)
                            {
                                if (mainmethod != "")
                                {
                                    throw new Exception("Have too mush EntryPoint,Check it.");
                                }
                                mainmethod = key;
                            }
                        }
                    }
                }
            }
            if (mainmethod == "")
            {
                throw new Exception("Can't find EntryPoint,Check it.");
            }
            else
            {
                //单一默认入口 Single default entry
                logger.Log("Find entrypoint:" + mainmethod);
            }

            outModule.mainMethod = mainmethod;
            this.LinkCode(mainmethod);
            //this.findFirstFunc();//得找到第一个函数 Have to find the first function
            //然后给每个method 分配一个func addr Then assign a func addr to each method
            //还需要对所有的call 做一次地址转换 Also need to do an address translation for all calls

            //this.outModule.Build();
            return(outModule);
        }
        private int _ConvertCall(JavaMethod method, OpCode src, NeoMethod to)
        {
            _Convert1by1(Pure.VM.OpCode.NOP, src, to);
            var cc   = method.DeclaringType.classfile.constantpool;
            var c    = cc[src.arg1] as javaloader.ClassFile.ConstantPoolItemMethodref;
            var name = c.Class + "::" + c.Name;

            List <string> paramTypes = new List <string>();
            string        returntype;

            JavaMethod.scanTypes(c.Signature, out returntype, paramTypes);


            JavaClass  javaclass   = null;
            JavaMethod _javamethod = null;

            if (this.srcModule.classes.ContainsKey(c.Class))
            {
                javaclass = this.srcModule.classes[c.Class];
                if (javaclass.methods.ContainsKey(c.Name + c.Signature))
                {
                    _javamethod = javaclass.methods[c.Name + c.Signature];
                }
                else
                {
                    while (javaclass != null)
                    {
                        if (this.srcModule.classes.ContainsKey(javaclass.superClass))
                        {
                            javaclass = this.srcModule.classes[javaclass.superClass];
                            if (javaclass.methods.ContainsKey(c.Name + c.Signature))
                            {
                                _javamethod = javaclass.methods[c.Name + c.Signature];
                                break;
                            }
                        }
                        else
                        {
                            javaclass = null;
                        }
                    }
                }
            }
            int    calltype = 0;
            string callname = "";

            byte[]         callhash = null;
            Pure.VM.OpCode callcode = Pure.VM.OpCode.NOP;
            if (IsNonCall(_javamethod))
            {
                return(0);
            }
            else if (IsOpCall(_javamethod, src, out callname))
            {
                if (System.Enum.TryParse <Pure.VM.OpCode>(callname, out callcode))
                {
                    calltype = 2;
                }
                else
                {
                    throw new Exception("Can not find OpCall:" + callname);
                }
            }
            else if (IsSysCall(_javamethod, src, out callname))
            {
                calltype = 3;
            }
            else if (IsAppCall(_javamethod, src, out callhash))
            {
                calltype = 4;
            }
            else if (this.outModule.mapMethods.ContainsKey(c.Class + "::" + c.Name + c.Signature))
            {//this is a call
                calltype = 1;
            }
            else
            {
                if (name == "java.io.PrintStream::println")
                {//drop 1;
                    Console.WriteLine("logstr.");
                    _Convert1by1(Pure.VM.OpCode.DROP, src, to);
                    return(0);
                }
                else if (name == "java.math.BigInteger::<init>")
                {//do nothing
                    if (c.Signature == "([B)V")
                    {
                        return(0);
                    }
                    else if (c.Signature == "(Ljava/lang/String;)V")
                    {
                        throw new Exception("not support new BigInteger(string)");
                    }
                }
                else if (name == "java.math.BigInteger::add")
                {
                    _Convert1by1(Pure.VM.OpCode.ADD, src, to);
                    return(0);
                }
                else if (name == "java.math.BigInteger::subtract")
                {
                    _Convert1by1(Pure.VM.OpCode.SUB, src, to);
                    return(0);
                }
                else if (name == "java.math.BigInteger::multiply")
                {
                    _Convert1by1(Pure.VM.OpCode.MUL, src, to);
                    return(0);
                }
                else if (name == "java.math.BigInteger::divide")
                {
                    _Convert1by1(Pure.VM.OpCode.DIV, src, to);
                    return(0);
                }
                else if (name == "java.math.BigInteger::mod")
                {
                    _Convert1by1(Pure.VM.OpCode.MOD, src, to);
                    return(0);
                }
                else if (name == "java.math.BigInteger::compareTo")
                {
                    //need parse
                    _Convert1by1(Pure.VM.OpCode.SUB, src, to);
                    _Convert1by1(Pure.VM.OpCode.SIGN, null, to);
                    //_Convert1by1(Pure.VM.OpCode.DEC, src, to);
                    return(0);
                }
                // todo: what about java.lang.String::contentEquals?
                else if (name == "java.math.BigInteger::equals" ||
                         name == "java.lang.String::equals" ||
                         name == "kotlin.jvm.internal.Intrinsics::areEqual")
                {
                    _Convert1by1(Pure.VM.OpCode.NUMEQUAL, src, to);
                    //_Convert1by1(Pure.VM.OpCode.DEC, src, to);
                    return(0);
                }
                else if (name == "java.math.BigInteger::valueOf" ||
                         name == "java.math.BigInteger::intValue" ||
                         name == "java.lang.Boolean::valueOf" ||
                         name == "java.lang.Character::valueOf" ||
                         name == "java.lang.String::valueOf" ||
                         name == "java.lang.Long::valueOf" ||
                         name == "java.lang.Integer::valueOf" ||
                         name == "java.lang.Byte::valueOf" ||
                         name == "java.math.BigInteger::toByteArray")
                {
                    //donothing
                    return(0);
                }
                else if (name == "java.lang.Boolean::booleanValue" ||
                         name == "java.lang.Integer::integerValue" ||
                         name == "java.lang.Long::longValue" ||
                         name == "java.math.BigInteger::longValue")
                {
                    _Convert1by1(Pure.VM.OpCode.NOP, src, to);
                    return(0);
                }
                else if (name == "java.lang.String::hashCode")
                {
                    //java switch 的编译方式很奇怪
                    return(0);
                }
                else if (name == "java.lang.String::charAt")
                {
                    _ConvertPush(1, src, to);
                    _Convert1by1(Pure.VM.OpCode.SUBSTR, null, to);
                    return(0);
                }
                else if (name == "java.lang.String::length")
                {
                    _Convert1by1(Pure.VM.OpCode.SIZE, null, to);
                    return(0);
                }
                else if (c.Class == "java.lang.StringBuilder")
                {
                    return(_ConvertStringBuilder(c.Name, null, to));
                }
                else if (name == "java.util.Arrays::equals" ||
                         name == "kotlin.jvm.internal.Intrinsics::areEqual")
                {
                    _Convert1by1(Pure.VM.OpCode.EQUAL, null, to);
                    return(0);
                }
                else if (name == "kotlin.jvm.internal.Intrinsics::checkParameterIsNotNull")
                {
                    _Convert1by1(Pure.VM.OpCode.DROP, null, to);
                    _Convert1by1(Pure.VM.OpCode.DROP, null, to);
                    return(0);
                }
                else if (name == "kotlin.jvm.internal.Intrinsics::throwNpe")
                {
                    _Convert1by1(Pure.VM.OpCode.THROW, src, to);
                    return(0);
                }
            }

            if (calltype == 0)
            {
                throw new Exception("unknown call:" + name);
            }
            var pcount = paramTypes.Count;

            if (calltype == 2)
            {
                //opcode call
            }
            else
            {//翻转参数入栈顺序
                _Convert1by1(Pure.VM.OpCode.NOP, src, to);
                if (pcount <= 1)
                {
                }
                else if (pcount == 2)
                {
                    _Insert1(Pure.VM.OpCode.SWAP, "swap 2 param", to);
                }
                else if (pcount == 3)
                {
                    _InsertPush(2, "swap 0 and 2 param", to);
                    _Insert1(Pure.VM.OpCode.XSWAP, "", to);
                }
                else
                {
                    for (var i = 0; i < pcount / 2; i++)
                    {
                        int saveto = (pcount - 1 - i);
                        _InsertPush(saveto, "load" + saveto, to);
                        _Insert1(Pure.VM.OpCode.PICK, "", to);

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


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

                        _InsertPush(i + 1, "save to" + i + 1, to);
                        _Insert1(Pure.VM.OpCode.XSWAP, "", to);
                        _Insert1(Pure.VM.OpCode.DROP, "", to);
                    }
                }
            }
            if (calltype == 1)
            {
                var _c = _Convert1by1(Pure.VM.OpCode.CALL, null, to, new byte[] { 5, 0 });
                _c.needfixfunc = true;
                _c.srcfunc     = name + c.Signature;
                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 too 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(Pure.VM.OpCode.SYSCALL, null, to, outbytes);
                return(0);
            }
            else if (calltype == 4)
            {
                _Convert1by1(Pure.VM.OpCode.APPCALL, null, to, callhash);
            }

            return(0);
        }
Exemplo n.º 22
0
        private int ConvertCode(JavaMethod method, OpCode src, NeoMethod to)
        {
            int skipcount = 0;

            switch (src.code)
            {
            case javaloader.NormalizedByteCode.__nop:
                _Convert1by1(Pure.VM.OpCode.NOP, src, to);
                break;

            case javaloader.NormalizedByteCode.__return:
            case javaloader.NormalizedByteCode.__ireturn:
            case javaloader.NormalizedByteCode.__lreturn:
            case javaloader.NormalizedByteCode.__freturn:
            case javaloader.NormalizedByteCode.__dreturn:
            case javaloader.NormalizedByteCode.__areturn:
                //        //return 在外面特殊处理了
                _Convert1by1(Pure.VM.OpCode.RET, src, to);
                break;

            case javaloader.NormalizedByteCode.__pop:
                _Convert1by1(Pure.VM.OpCode.DROP, src, to);
                break;

            case javaloader.NormalizedByteCode.__pop2:    //pop2 这个指令有些鬼
                _Convert1by1(Pure.VM.OpCode.DROP, src, to);
                break;

            case javaloader.NormalizedByteCode.__getstatic:
            {
                _Convert1by1(Pure.VM.OpCode.NOP, src, to);

                var cc = method.DeclaringType.classfile.constantpool;
                var c  = cc[src.arg1] as javaloader.ClassFile.ConstantPoolItemFieldref;
                if (c.Class == "java.math.BigInteger")
                {
                    if (c.Name == "ONE")
                    {
                        _ConvertPush(1, src, to);
                    }
                    if (c.Name == "ZERO")
                    {
                        _ConvertPush(0, src, to);
                    }
                }
                else if (c.Class == "java.lang.System")
                {
                    if (c.Name == "out")
                    {
                        //donothing
                    }
                }
                else
                {
                    var m = method.DeclaringType.module;
                    if (m.classes.ContainsKey(c.Class))
                    {
                        var _tclass = m.classes[c.Class];
                        if (_tclass.IsEnum)
                        {
                            var v = _tclass.ConstValues[c.Name];
                            _ConvertPush(v, src, to);
                        }
                    }
                }
                //this.convertType.Push(c.Signature);
            }
            break;

            case javaloader.NormalizedByteCode.__ldc:
            {
                var cc   = method.DeclaringType.classfile.constantpool;
                var item = cc[src.arg1];
                if (item is javaloader.ClassFile.ConstantPoolItemString)
                {
                    var str = (item as javaloader.ClassFile.ConstantPoolItemString).Value;
                    _ConvertPush(Encoding.UTF8.GetBytes(str), src, to);
                }
                else if (item is javaloader.ClassFile.ConstantPoolItemLong)
                {
                    var v = (item as javaloader.ClassFile.ConstantPoolItemLong).Value;
                    _ConvertPush(v, src, to);
                }
                else if (item is javaloader.ClassFile.ConstantPoolItemInteger)
                {
                    var v = (item as javaloader.ClassFile.ConstantPoolItemInteger).Value;
                    _ConvertPush(v, src, to);
                }
                else
                {
                    throw new Exception("not parse.");
                }
            }
            break;

            case javaloader.NormalizedByteCode.__iconst:

                _ConvertPush(src.arg1, src, to);
                break;

            case javaloader.NormalizedByteCode.__lconst_1:
                _ConvertPush(1, src, to);
                break;

            case javaloader.NormalizedByteCode.__lconst_0:
                _ConvertPush(0, src, to);
                break;

            case javaloader.NormalizedByteCode.__aconst_null:
                _ConvertPush(0, src, to);
                break;

            case javaloader.NormalizedByteCode.__newarray:
            case javaloader.NormalizedByteCode.__anewarray:
                skipcount = _ConvertNewArray(method, src, to);
                break;

            case javaloader.NormalizedByteCode.__astore:
            case javaloader.NormalizedByteCode.__istore:
            case javaloader.NormalizedByteCode.__lstore:
                _ConvertStLoc(method, src, to, src.arg1);
                break;

            case javaloader.NormalizedByteCode.__aload:
            case javaloader.NormalizedByteCode.__iload:
            case javaloader.NormalizedByteCode.__lload:
                _ConvertLdLoc(method, src, to, src.arg1);
                break;

            case javaloader.NormalizedByteCode.__baload:
                _ConvertPush(1, src, to);
                _Convert1by1(Pure.VM.OpCode.SUBSTR, null, to);
                break;

            case javaloader.NormalizedByteCode.__aaload:
            case javaloader.NormalizedByteCode.__iaload:
            case javaloader.NormalizedByteCode.__laload:
                _Convert1by1(Pure.VM.OpCode.PICKITEM, src, to);
                break;

            case javaloader.NormalizedByteCode.__iastore:
            case javaloader.NormalizedByteCode.__aastore:
            case javaloader.NormalizedByteCode.__lastore:
                _Convert1by1(Pure.VM.OpCode.SETITEM, src, to);
                break;

            case javaloader.NormalizedByteCode.__arraylength:
                _Convert1by1(Pure.VM.OpCode.ARRAYSIZE, src, to);
                break;

            case javaloader.NormalizedByteCode.__invokevirtual:
            case javaloader.NormalizedByteCode.__invokestatic:
            case javaloader.NormalizedByteCode.__invokespecial:
            {
                _ConvertCall(method, src, to);
            }
            break;

            case javaloader.NormalizedByteCode.__iinc:
                _Convert1by1(Pure.VM.OpCode.NOP, src, to);
                {
                    _Insert1(Pure.VM.OpCode.DUPFROMALTSTACK, "", to);
                    _InsertPush(src.arg1, "", to);
                    _Insert1(Pure.VM.OpCode.PICKITEM, "", to);
                    _InsertPush(src.arg2, "", to);
                    _Insert1(Pure.VM.OpCode.ADD, "", to);

                    _Insert1(Pure.VM.OpCode.DUPFROMALTSTACK, "", to); //array
                    _InsertPush(src.arg1, "", to);                    //index
                    _InsertPush(2, "", to);
                    _Insert1(Pure.VM.OpCode.ROLL, "", to);
                    _Insert1(Pure.VM.OpCode.SETITEM, "", to);
                }
                //_Convert1by1(Pure.VM.OpCode.INC, src, to);

                break;

            case javaloader.NormalizedByteCode.__lcmp:
                _Convert1by1(Pure.VM.OpCode.SUB, src, to);
                _Convert1by1(Pure.VM.OpCode.SIGN, null, to);
                break;

            //    case CodeEx.Ldloc_0:
            //        _ConvertLdLoc(src, to, 0);
            //        break;
            //    case CodeEx.Ldloc_1:
            //        _ConvertLdLoc(src, to, 1);
            //        break;
            //    case CodeEx.Ldloc_2:
            //        _ConvertLdLoc(src, to, 2);
            //        break;
            //    case CodeEx.Ldloc_3:
            //        _ConvertLdLoc(src, to, 3);
            //        break;
            //    case CodeEx.Ldloc_S:
            //        _ConvertLdLoc(src, to, src.tokenI32);
            //        break;

            //    case CodeEx.Ldarg_0:
            //        _ConvertLdArg(src, to, 0);
            //        break;
            //    case CodeEx.Ldarg_1:
            //        _ConvertLdArg(src, to, 1);
            //        break;
            //    case CodeEx.Ldarg_2:
            //        _ConvertLdArg(src, to, 2);
            //        break;
            //    case CodeEx.Ldarg_3:
            //        _ConvertLdArg(src, to, 3);
            //        break;
            //    case CodeEx.Ldarg_S:
            //    case CodeEx.Ldarg:
            //        _ConvertLdArg(src, to, src.tokenI32);
            //        break;
            //需要地址轉換的情況
            case javaloader.NormalizedByteCode.__goto:
            {
                var code = _Convert1by1(Pure.VM.OpCode.JMP, src, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.arg1 + src.addr;
            }
            break;

            //    case CodeEx.Br_S:
            //        {
            //            var code = _Convert1by1(Pure.VM.OpCode.JMP, src, to, new byte[] { 0, 0 });
            //            code.needfix = true;
            //            code.srcaddr = src.tokenAddr_Index;
            //        }

            //        break;
            case javaloader.NormalizedByteCode.__if_acmpeq:
            {
                _Convert1by1(Pure.VM.OpCode.EQUAL, null, to);
                var code = _Convert1by1(Pure.VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.addr + src.arg1;
            }
            break;

            case javaloader.NormalizedByteCode.__if_acmpne:
            {
                _Convert1by1(Pure.VM.OpCode.EQUAL, null, to);
                _Convert1by1(Pure.VM.OpCode.NOT, null, to);
                var code = _Convert1by1(Pure.VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.addr + src.arg1;
            }
            break;

            case javaloader.NormalizedByteCode.__if_icmpeq:
            {
                _Convert1by1(Pure.VM.OpCode.NUMEQUAL, null, to);
                var code = _Convert1by1(Pure.VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.addr + src.arg1;
            }
            break;

            case javaloader.NormalizedByteCode.__if_icmpne:
            {
                _Convert1by1(Pure.VM.OpCode.NUMNOTEQUAL, null, to);
                var code = _Convert1by1(Pure.VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.addr + src.arg1;
            }
            break;

            case javaloader.NormalizedByteCode.__ifne:
            {
                _ConvertPush(0, src, to);        //和0比较
                _Convert1by1(Pure.VM.OpCode.NUMNOTEQUAL, null, to);
                var code = _Convert1by1(Pure.VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.arg1 + src.addr;
            }
            break;

            case javaloader.NormalizedByteCode.__ifeq:
            {
                _ConvertPush(0, src, to);        //和0比较
                _Convert1by1(Pure.VM.OpCode.NUMEQUAL, null, to);
                var code = _Convert1by1(Pure.VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.arg1 + src.addr;
            }
            break;

            case javaloader.NormalizedByteCode.__iflt:
            {
                _ConvertPush(0, src, to);        //和0比较
                _Convert1by1(Pure.VM.OpCode.LT, null, to);
                var code = _Convert1by1(Pure.VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.arg1 + src.addr;
            }
            break;

            case javaloader.NormalizedByteCode.__if_icmplt:
            {
                _Convert1by1(Pure.VM.OpCode.LT, src, to);
                var code = _Convert1by1(Pure.VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.addr + src.arg1;
            }
            break;

            case javaloader.NormalizedByteCode.__ifle:
            {
                _ConvertPush(0, src, to);        //和0比较
                _Convert1by1(Pure.VM.OpCode.LTE, null, to);
                var code = _Convert1by1(Pure.VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.addr + src.arg1;
            }
            break;

            case javaloader.NormalizedByteCode.__if_icmple:
            {
                _Convert1by1(Pure.VM.OpCode.LTE, src, to);
                var code = _Convert1by1(Pure.VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.addr + src.arg1;
            }
            break;

            case javaloader.NormalizedByteCode.__ifgt:
            {
                _ConvertPush(0, src, to);        //和0比较
                _Convert1by1(Pure.VM.OpCode.GT, null, to);
                var code = _Convert1by1(Pure.VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.addr + src.arg1;
            }
            break;

            case javaloader.NormalizedByteCode.__if_icmpgt:
            {
                _Convert1by1(Pure.VM.OpCode.GT, src, to);
                var code = _Convert1by1(Pure.VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.addr + src.arg1;
            }
            break;

            case javaloader.NormalizedByteCode.__ifge:
            {
                _ConvertPush(0, src, to);        //和0比较
                _Convert1by1(Pure.VM.OpCode.GTE, null, to);
                var code = _Convert1by1(Pure.VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.addr + src.arg1;
            }
            break;

            case javaloader.NormalizedByteCode.__if_icmpge:
            {
                _Convert1by1(Pure.VM.OpCode.GTE, null, to);
                var code = _Convert1by1(Pure.VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.addr + src.arg1;
            }
            break;

            case javaloader.NormalizedByteCode.__ifnull:
            {
                _ConvertPush(0, src, to);        //和0比较
                _Convert1by1(Pure.VM.OpCode.NUMEQUAL, null, to);
                var code = _Convert1by1(Pure.VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.addr + src.arg1;
            }
            break;

            case javaloader.NormalizedByteCode.__ifnonnull:
            {
                //实际上ifnonnull 有可能是kotlin自动插入的代码,他有个套路
                //ifnonnull 跳过 一个throw,isnon 就 throw
                //Module.VM实际上没有null这个类型,要识别出这个套路,编译出更合理的代码
                skipcount = _ConvertIfNonNull(method, src, to);
            }
            break;

            //    //Stack
            case javaloader.NormalizedByteCode.__dup:
                _Convert1by1(Pure.VM.OpCode.DUP, src, to);
                break;

            //    //Bitwise logic
            case javaloader.NormalizedByteCode.__iand:
            case javaloader.NormalizedByteCode.__land:
                _Convert1by1(Pure.VM.OpCode.AND, src, to);
                break;

            case javaloader.NormalizedByteCode.__ior:
            case javaloader.NormalizedByteCode.__lor:
                _Convert1by1(Pure.VM.OpCode.OR, src, to);
                break;

            case javaloader.NormalizedByteCode.__ixor:
            case javaloader.NormalizedByteCode.__lxor:
                _Convert1by1(Pure.VM.OpCode.XOR, src, to);
                break;


            case javaloader.NormalizedByteCode.__iadd:
            case javaloader.NormalizedByteCode.__ladd:
                _Convert1by1(Pure.VM.OpCode.ADD, src, to);
                break;

            case javaloader.NormalizedByteCode.__isub:
            case javaloader.NormalizedByteCode.__lsub:
                _Convert1by1(Pure.VM.OpCode.SUB, src, to);
                break;

            case javaloader.NormalizedByteCode.__imul:
            case javaloader.NormalizedByteCode.__lmul:
                _Convert1by1(Pure.VM.OpCode.MUL, src, to);
                break;

            case javaloader.NormalizedByteCode.__idiv:
            case javaloader.NormalizedByteCode.__ldiv:
                _Convert1by1(Pure.VM.OpCode.DIV, src, to);
                break;

            case javaloader.NormalizedByteCode.__irem:
            case javaloader.NormalizedByteCode.__lrem:
                _Convert1by1(Pure.VM.OpCode.MOD, src, to);
                break;

            case javaloader.NormalizedByteCode.__new:
                skipcount = _ConvertNew(method, src, to);

                break;
            //    case CodeEx.Neg:
            //        _Convert1by1(Pure.VM.OpCode.NEGATE, src, to);
            //        break;
            //    case CodeEx.Shl:
            //        _Convert1by1(Pure.VM.OpCode.SHL, src, to);
            //        break;
            //    case CodeEx.Shr:
            //    case CodeEx.Shr_Un:
            //        _Convert1by1(Pure.VM.OpCode.SHR, src, to);
            //        break;

            //    //logic
            //    case CodeEx.Clt:
            //    case CodeEx.Clt_Un:
            //        _Convert1by1(Pure.VM.OpCode.LT, src, to);
            //        break;
            //    case CodeEx.Cgt:
            //    case CodeEx.Cgt_Un:
            //        _Convert1by1(Pure.VM.OpCode.GT, src, to);
            //        break;
            //    case CodeEx.Ceq:
            //        _Convert1by1(Pure.VM.OpCode.NUMEQUAL, src, to);
            //        break;

            //    //call
            //    case CodeEx.Call:
            //    case CodeEx.Callvirt:
            //        _ConvertCall(src, to);
            //        break;

            //    //用上一个参数作为数量,new 一个数组
            //    case CodeEx.Newarr:
            //        skipcount = _ConvertNewArr(method, src, to);
            //        break;


            //    //array
            //    case CodeEx.Ldelem_U1://用意为byte[] 取一部分.....
            //        _ConvertPush(1, src, to);
            //        _Convert1by1(Pure.VM.OpCode.SUBSTR, null, to);
            //        break;
            //    case CodeEx.Ldelem_Any:
            //    case CodeEx.Ldelem_I:
            //    case CodeEx.Ldelem_I1:
            //    case CodeEx.Ldelem_I2:
            //    case CodeEx.Ldelem_I4:
            //    case CodeEx.Ldelem_I8:
            //    case CodeEx.Ldelem_R4:
            //    case CodeEx.Ldelem_R8:
            //    case CodeEx.Ldelem_Ref:
            //    case CodeEx.Ldelem_U2:
            //    case CodeEx.Ldelem_U4:
            //        _Convert1by1(Pure.VM.OpCode.PICKITEM, src, to);
            //        break;
            //    case CodeEx.Ldlen:
            //        _Convert1by1(Pure.VM.OpCode.ARRAYSIZE, src, to);
            //        break;

            //    case CodeEx.Castclass:
            //        break;
            case javaloader.NormalizedByteCode.__i2c:
            case javaloader.NormalizedByteCode.__checkcast:
                break;
            //    case CodeEx.Box:
            //    case CodeEx.Unbox:
            //    case CodeEx.Unbox_Any:
            //    case CodeEx.Break:
            //    //也有可能以后利用这个断点调试
            //    case CodeEx.Conv_I:
            //    case CodeEx.Conv_I1:
            //    case CodeEx.Conv_I2:
            //    case CodeEx.Conv_I4:
            //    case CodeEx.Conv_I8:
            //    case CodeEx.Conv_Ovf_I:
            //    case CodeEx.Conv_Ovf_I_Un:
            //    case CodeEx.Conv_Ovf_I1:
            //    case CodeEx.Conv_Ovf_I1_Un:
            //    case CodeEx.Conv_Ovf_I2:
            //    case CodeEx.Conv_Ovf_I2_Un:
            //    case CodeEx.Conv_Ovf_I4:
            //    case CodeEx.Conv_Ovf_I4_Un:
            //    case CodeEx.Conv_Ovf_I8:
            //    case CodeEx.Conv_Ovf_I8_Un:
            //    case CodeEx.Conv_Ovf_U:
            //    case CodeEx.Conv_Ovf_U_Un:
            //    case CodeEx.Conv_Ovf_U1:
            //    case CodeEx.Conv_Ovf_U1_Un:
            //    case CodeEx.Conv_Ovf_U2:
            //    case CodeEx.Conv_Ovf_U2_Un:
            //    case CodeEx.Conv_Ovf_U4:
            //    case CodeEx.Conv_Ovf_U4_Un:
            //    case CodeEx.Conv_Ovf_U8:
            //    case CodeEx.Conv_Ovf_U8_Un:
            //    case CodeEx.Conv_U:
            //    case CodeEx.Conv_U1:
            //    case CodeEx.Conv_U2:
            //    case CodeEx.Conv_U4:
            //    case CodeEx.Conv_U8:
            //        break;

            //    ///////////////////////////////////////////////
            //    //以下因为支持结构体而出现
            //    //加载一个引用,这里改为加载一个pos值
            //    case CodeEx.Ldloca:
            //    case CodeEx.Ldloca_S:
            //        _ConvertLdLocA(src, to, src.tokenI32);
            //        break;
            //    case CodeEx.Initobj:
            //        _ConvertInitObj(src, to);
            //        break;
            //    case CodeEx.Stfld:
            //        _ConvertStfld(src, to);
            //        break;
            //    case CodeEx.Ldfld:
            //        _ConvertLdfld(src, to);
            //        break;
            default:
#if WITHPDB
                //throw new Exception("unsupported instruction " + src.code);
                logger.Log("not support code" + src.code);
                break;
#else
                throw new Exception("unsupported instruction " + src.code);
#endif
            }

            return(skipcount);
        }
Exemplo n.º 23
0
        public QurasModule Convert(JavaModule _in)
        {
            this.srcModule = _in;
            //logger.Log("beginConvert.");
            this.outModule = new QurasModule(this.logger);
            foreach (var c in _in.classes.Values)
            {
                if (c.skip)
                {
                    continue;
                }
                foreach (var m in c.methods)
                {
                    if (m.Value.skip)
                    {
                        continue;
                    }
                    if (m.Key[0] == '<')
                    {
                        continue;                 //系統函數不要
                    }
                    NeoMethod nm = new NeoMethod();
                    nm.name                       = c.classfile.Name + "::" + m.Key;
                    nm.displayName                = m.Key;
                    nm.isPublic                   = m.Value.method.IsPublic;
                    this.methodLink[m.Value]      = nm;
                    outModule.mapMethods[nm.name] = nm;
                }
            }

            foreach (var c in _in.classes.Values)
            {
                if (c.skip)
                {
                    continue;
                }
                foreach (var m in c.methods)
                {
                    if (m.Value.skip)
                    {
                        continue;
                    }
                    if (m.Key[0] == '<')
                    {
                        continue;                 //系統函數不要
                    }
                    var nm = this.methodLink[m.Value];
                    //try
                    {
                        this.ConvertMethod(m.Value, nm);
                    }
                    //catch (Exception err)
                    //{
                    //    logger.Log("error:" + err.Message);
                    //}
                }
            }
            //转换完了,做个link,全部拼到一起
            string mainmethod = "";

            foreach (var key in outModule.mapMethods.Keys)
            {
                var name = key.Substring(key.IndexOf("::") + 2);
                var i    = name.IndexOf('(');
                name = name.Substring(0, i);

                if (name == ("Main"))
                {
                    var m = outModule.mapMethods[key];
                    foreach (var l in this.methodLink)
                    {
                        if (l.Value == m)
                        {
                            var srcm = l.Key;
                            if (srcm.DeclaringType.superClass == "org.neo.smartcontract.framework.SmartContract")
                            {
                                logger.Log("Find entrypoint:" + key);
                                if (mainmethod != "")
                                {
                                    throw new Exception("Have too mush EntryPoint,Check it.");
                                }
                                mainmethod = key;
                            }
                        }
                    }
                }
            }
            if (mainmethod == "")
            {
                throw new Exception("Can't find Main Method from SmartContract,Check it.");
            }
            outModule.mainMethod = mainmethod;
            //得找到第一个函数
            this.LinkCode(mainmethod);
            //this.findFirstFunc();//得找到第一个函数
            //然后给每个method 分配一个func addr
            //还需要对所有的call 做一次地址转换

            //this.outModule.Build();
            return(outModule);
        }
Exemplo n.º 24
0
        public NeoModule Convert(ILModule _in)
        {
            //logger.Log("beginConvert.");
            this.outModule = new NeoModule(this.logger);
            foreach (var t in _in.mapType)
            {
                if (t.Key[0] == '<')
                {
                    continue;                 //系统的,不要
                }
                if (t.Key.Contains("_API_"))
                {
                    continue;                         //api的,不要
                }
                if (t.Key.Contains(".My."))
                {
                    continue;//vb system
                }
                foreach (var m in t.Value.methods)
                {
                    if (m.Value.method == null)
                    {
                        continue;
                    }
                    if (m.Value.method.IsAddOn || m.Value.method.IsRemoveOn)
                    {
                        continue;//event 自动生成的代码,不要
                    }
                    NeoMethod nm = new NeoMethod();
                    if (m.Key == ".cctor")
                    {
                        CctorSubVM.Parse(m.Value, this.outModule);
                        continue;
                    }
                    if (m.Value.method.IsConstructor)
                    {
                        continue;
                    }
                    nm._namespace  = m.Value.method.DeclaringType.FullName;
                    nm.name        = m.Value.method.FullName;
                    nm.displayName = m.Value.method.Name;

                    Mono.Collections.Generic.Collection <Mono.Cecil.CustomAttribute> ca = m.Value.method.CustomAttributes;
                    foreach (var attr in ca)
                    {
                        if (attr.AttributeType.Name == "DisplayNameAttribute")
                        {
                            nm.displayName = (string)attr.ConstructorArguments[0].Value;
                        }
                    }

                    nm.isPublic = m.Value.method.IsPublic;
                    this.methodLink[m.Value]      = nm;
                    outModule.mapMethods[nm.name] = nm;
                }
                foreach (var e in t.Value.fields)
                {
                    if (e.Value.isEvent)
                    {
                        NeoEvent ae = new NeoEvent();
                        ae._namespace  = e.Value.field.DeclaringType.FullName;
                        ae.name        = ae._namespace + "::" + e.Key;
                        ae.displayName = e.Value.displayName;
                        ae.returntype  = e.Value.returntype;
                        ae.paramtypes  = e.Value.paramtypes;
                        outModule.mapEvents[ae.name] = ae;
                    }
                }
            }

            Dictionary <byte, string> spmains = new Dictionary <byte, string>();

            foreach (var t in _in.mapType)
            {
                if (t.Key[0] == '<')
                {
                    continue;                 //系统的,不要
                }
                if (t.Key.Contains("_API_"))
                {
                    continue;                         //api的,不要
                }
                if (t.Key.Contains(".My."))
                {
                    continue;//vb system
                }
                foreach (var m in t.Value.methods)
                {
                    if (m.Value.method == null)
                    {
                        continue;
                    }
                    if (m.Key == ".cctor")
                    {
                        continue;
                    }
                    if (m.Value.method.IsAddOn || m.Value.method.IsRemoveOn)
                    {
                        continue;//event 自动生成的代码,不要
                    }
                    var  nm = this.methodLink[m.Value];
                    byte entryid;
                    if (IsEntryCall(m.Value.method, out entryid))
                    {
                        spmains[entryid] = nm.name;
                        logger.Log("Find entrypoint:[" + entryid + "]" + nm.name);
                    }

                    //try
                    {
                        nm.returntype = m.Value.returntype;
                        foreach (var src in m.Value.paramtypes)
                        {
                            nm.paramtypes.Add(new NeoParam(src.name, src.type));
                        }

                        byte[] outcall; string name;
                        if (IsAppCall(m.Value.method, out outcall))
                        {
                            continue;
                        }
                        if (IsNonCall(m.Value.method))
                        {
                            continue;
                        }
                        if (IsOpCall(m.Value.method, out name))
                        {
                            continue;
                        }
                        if (IsSysCall(m.Value.method, out name))
                        {
                            continue;
                        }

                        this.ConvertMethod(m.Value, nm);
                    }
                    //catch (Exception err)
                    //{
                    //    logger.Log("error:" + err.Message);
                    //}
                }
            }
            //转换完了,做个link,全部拼到一起
            string mainmethod = "";

            foreach (var key in outModule.mapMethods.Keys)
            {
                if (key.Contains("::Main("))
                {
                    NeoMethod m = outModule.mapMethods[key];

                    foreach (var l in this.methodLink)
                    {
                        if (l.Value == m)
                        {
                            var srcm = l.Key.method;
                            if (srcm.DeclaringType.BaseType.Name == "SmartContract")
                            {
                                if (mainmethod != "")
                                {
                                    throw new Exception("Have too mush EntryPoint,Check it.");
                                }
                                mainmethod = key;
                            }
                        }
                    }
                }
            }
            if (mainmethod == "" && spmains.Count == 0)
            {
                throw new Exception("Can't find EntryPoint,Check it.");
            }
            else if (mainmethod != "" && spmains.Count > 0)
            {
                throw new Exception("Have Main Method and Spec EntryPoint sametime,Check it.");
            }
            else if (mainmethod != "")
            {
                //单一默认入口
                logger.Log("Find entrypoint:" + mainmethod);
            }
            else if (spmains.Count > 0) //拥有条件入口的情况
            {
                mainmethod = this.CreateJmpMain(spmains);
            }

            outModule.mainMethod = mainmethod;
            this.LinkCode(mainmethod);
            //this.findFirstFunc();//得找到第一个函数
            //然后给每个method 分配一个func addr
            //还需要对所有的call 做一次地址转换

            //this.outModule.Build();
            return(outModule);
        }
Exemplo n.º 25
0
        public NeoModule Convert(ILModule _in, ConvOption option = null)
        {
            this.inModule  = _in;
            this.outModule = new NeoModule(this.logger)
            {
                option = option ?? ConvOption.Default
            };
            foreach (var t in _in.mapType)
            {
                if (t.Key.Contains("<"))
                {
                    continue;                        //skip system type
                }
                if (t.Key.Contains("_API_"))
                {
                    continue;                          // skip api
                }
                if (t.Key.Contains(".My."))
                {
                    continue;                         //vb system
                }
                foreach (var m in t.Value.methods)
                {
                    if (m.Value.method == null)
                    {
                        continue;
                    }
                    if (m.Value.method.IsAddOn || m.Value.method.IsRemoveOn)
                    {
                        continue;                                                      // skip the code generated by event
                    }
                    if (m.Value.method.Is_ctor())
                    {
                        continue;
                    }
                    if (m.Value.method.Is_cctor())
                    {
                        //if cctor contains sth can not be as a const value.
                        //  then need 1.record these cctor's code.
                        //            2.insert them to main function
                        CctorSubVM.Parse(m.Value, this.outModule);
                        continue;
                    }

                    NeoMethod nm = new NeoMethod(m.Value);
                    this.methodLink[m.Value]      = nm;
                    outModule.mapMethods[nm.name] = nm;
                }

                foreach (var e in t.Value.fields)
                {
                    if (e.Value.isEvent)
                    {
                        NeoEvent ae = new NeoEvent(e.Value);
                        outModule.mapEvents[ae.name] = ae;
                    }
                    else if (e.Value.field.IsStatic)
                    {
                        var _fieldindex = outModule.mapFields.Count;
                        var field       = new NeoField(e.Key, e.Value.type, _fieldindex);
                        outModule.mapFields[e.Value.field.FullName] = field;
                    }
                }
            }

            var keys = new List <string>(_in.mapType.Keys);

            foreach (var key in keys)
            {
                var value = _in.mapType[key];
                if (key.Contains("<"))
                {
                    continue;                    // skip system typee
                }
                if (key.Contains("_API_"))
                {
                    continue;                        // skip api
                }
                if (key.Contains(".My."))
                {
                    continue;                       //vb system
                }
                foreach (var m in value.methods)
                {
                    if (m.Value.method == null)
                    {
                        continue;
                    }
                    if (m.Value.method.Is_cctor())
                    {
                        continue;
                    }
                    if (m.Value.method.IsAddOn || m.Value.method.IsRemoveOn)
                    {
                        continue;                                                      // skip the code generated by event
                    }
                    var nm = this.methodLink[m.Value];

                    //try
                    {
                        nm.returntype = m.Value.returntype;

                        foreach (var src in m.Value.paramtypes)
                        {
                            nm.paramtypes.Add(new NeoParam(src.name, src.type));
                        }

                        if (IsContractCall(m.Value.method, out byte[] outcall))
Exemplo n.º 26
0
        private int ConvertCode(ILMethod method, OpCode src, NeoMethod to)
        {
            int skipcount = 0;

            switch (src.code)
            {
            case CodeEx.Nop:
                _Convert1by1(VM.OpCode.NOP, src, to);
                break;

            case CodeEx.Ret:
                //return 在外面特殊处理了
                _Insert1(VM.OpCode.RET, null, to);
                break;

            case CodeEx.Pop:
                _Convert1by1(VM.OpCode.DROP, src, to);
                break;

            case CodeEx.Ldnull:
                _ConvertPush(new byte[0], src, to);
                break;

            case CodeEx.Ldc_I4:
            case CodeEx.Ldc_I4_S:
                skipcount = _ConvertPushI4WithConv(method, src.tokenI32, src, to);
                break;

            case CodeEx.Ldc_I4_0:
                _ConvertPush(0, src, to);
                break;

            case CodeEx.Ldc_I4_1:
                _ConvertPush(1, src, to);
                break;

            case CodeEx.Ldc_I4_2:
                _ConvertPush(2, src, to);
                break;

            case CodeEx.Ldc_I4_3:
                _ConvertPush(3, src, to);
                break;

            case CodeEx.Ldc_I4_4:
                _ConvertPush(4, src, to);
                break;

            case CodeEx.Ldc_I4_5:
                _ConvertPush(5, src, to);
                break;

            case CodeEx.Ldc_I4_6:
                _ConvertPush(6, src, to);
                break;

            case CodeEx.Ldc_I4_7:
                _ConvertPush(7, src, to);
                break;

            case CodeEx.Ldc_I4_8:
                _ConvertPush(8, src, to);
                break;

            case CodeEx.Ldc_I4_M1:
                skipcount = _ConvertPushI4WithConv(method, -1, src, to);
                break;

            case CodeEx.Ldc_I8:
                skipcount = _ConvertPushI8WithConv(method, src.tokenI64, src, to);
                break;

            case CodeEx.Ldstr:
                _ConvertPush(Encoding.UTF8.GetBytes(src.tokenStr), src, to);
                break;

            case CodeEx.Stloc_0:
                _ConvertStLoc(method, src, to, 0);
                break;

            case CodeEx.Stloc_1:
                _ConvertStLoc(method, src, to, 1);
                break;

            case CodeEx.Stloc_2:
                _ConvertStLoc(method, src, to, 2);
                break;

            case CodeEx.Stloc_3:
                _ConvertStLoc(method, src, to, 3);
                break;

            case CodeEx.Stloc_S:
                _ConvertStLoc(method, src, to, src.tokenI32);
                break;

            case CodeEx.Ldloc_0:
                _ConvertLdLoc(method, src, to, 0);
                break;

            case CodeEx.Ldloc_1:
                _ConvertLdLoc(method, src, to, 1);
                break;

            case CodeEx.Ldloc_2:
                _ConvertLdLoc(method, src, to, 2);
                break;

            case CodeEx.Ldloc_3:
                _ConvertLdLoc(method, src, to, 3);
                break;

            case CodeEx.Ldloc_S:
                _ConvertLdLoc(method, src, to, src.tokenI32);
                break;

            case CodeEx.Ldarg_0:
                _ConvertLdArg(src, to, 0);
                break;

            case CodeEx.Ldarg_1:
                _ConvertLdArg(src, to, 1);
                break;

            case CodeEx.Ldarg_2:
                _ConvertLdArg(src, to, 2);
                break;

            case CodeEx.Ldarg_3:
                _ConvertLdArg(src, to, 3);
                break;

            case CodeEx.Ldarg_S:
            case CodeEx.Ldarg:
            case CodeEx.Ldarga:
            case CodeEx.Ldarga_S:
                _ConvertLdArg(src, to, src.tokenI32);
                break;

            case CodeEx.Starg_S:
            case CodeEx.Starg:
                _ConvertStArg(src, to, src.tokenI32);
                break;

            //需要地址轉換的情況
            case CodeEx.Br:
            case CodeEx.Br_S:
            case CodeEx.Leave:
            case CodeEx.Leave_S:
            {
                var code = _Convert1by1(VM.OpCode.JMP, src, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.tokenAddr_Index;
            }

            break;

            case CodeEx.Switch:
            {
                throw new Exception("need neo.VM update.");
                //var addrdata = new byte[src.tokenAddr_Switch.Length * 2 + 2];
                //var shortaddrcount = (UInt16)src.tokenAddr_Switch.Length;
                //var data = BitConverter.GetBytes(shortaddrcount);
                //addrdata[0] = data[0];
                //addrdata[1] = data[1];
                //var code = _Convert1by1(VM.OpCode.SWITCH, src, to, addrdata);
                //code.needfix = true;
                //code.srcaddrswitch = new int[shortaddrcount];
                //for (var i = 0; i < shortaddrcount; i++)
                //{
                //    code.srcaddrswitch[i] = src.tokenAddr_Switch[i];
                //}
            }
            break;

            case CodeEx.Brtrue:
            case CodeEx.Brtrue_S:
            {
                var code = _Convert1by1(VM.OpCode.JMPIF, src, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.tokenAddr_Index;
            }
            break;

            case CodeEx.Brfalse:
            case CodeEx.Brfalse_S:
            {
                var code = _Convert1by1(VM.OpCode.JMPIFNOT, src, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.tokenAddr_Index;
            }
            break;

            case CodeEx.Beq:
            case CodeEx.Beq_S:
            {
                _Convert1by1(VM.OpCode.NUMEQUAL, src, to);
                var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.tokenAddr_Index;
            }
            break;

            case CodeEx.Bne_Un:
            case CodeEx.Bne_Un_S:
            {
                _Convert1by1(VM.OpCode.ABS, src, to);
                _Convert1by1(VM.OpCode.SWAP, null, to);
                _Convert1by1(VM.OpCode.ABS, null, to);
                _Convert1by1(VM.OpCode.SWAP, null, to);
                _Convert1by1(VM.OpCode.NUMNOTEQUAL, null, to);
                var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.tokenAddr_Index;
            }
            break;

            case CodeEx.Blt:
            case CodeEx.Blt_S:
            {
                _Convert1by1(VM.OpCode.LT, src, to);
                var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.tokenAddr_Index;
            }
            break;

            case CodeEx.Blt_Un:
            case CodeEx.Blt_Un_S:
            {
                _Convert1by1(VM.OpCode.ABS, src, to);
                _Convert1by1(VM.OpCode.SWAP, null, to);
                _Convert1by1(VM.OpCode.ABS, null, to);
                _Convert1by1(VM.OpCode.SWAP, null, to);
                _Convert1by1(VM.OpCode.LT, null, to);
                var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.tokenAddr_Index;
            }
            break;

            case CodeEx.Ble:
            case CodeEx.Ble_S:
            {
                _Convert1by1(VM.OpCode.LTE, src, to);
                var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.tokenAddr_Index;
            }
            break;

            case CodeEx.Ble_Un:
            case CodeEx.Ble_Un_S:
            {
                _Convert1by1(VM.OpCode.ABS, src, to);
                _Convert1by1(VM.OpCode.SWAP, null, to);
                _Convert1by1(VM.OpCode.ABS, null, to);
                _Convert1by1(VM.OpCode.SWAP, null, to);
                _Convert1by1(VM.OpCode.LTE, null, to);
                var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.tokenAddr_Index;
            }
            break;

            case CodeEx.Bgt:
            case CodeEx.Bgt_S:
            {
                _Convert1by1(VM.OpCode.GT, src, to);
                var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.tokenAddr_Index;
            }
            break;

            case CodeEx.Bgt_Un:
            case CodeEx.Bgt_Un_S:
            {
                _Convert1by1(VM.OpCode.ABS, src, to);
                _Convert1by1(VM.OpCode.SWAP, null, to);
                _Convert1by1(VM.OpCode.ABS, null, to);
                _Convert1by1(VM.OpCode.SWAP, null, to);
                _Convert1by1(VM.OpCode.GT, null, to);
                var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.tokenAddr_Index;
            }
            break;

            case CodeEx.Bge:
            case CodeEx.Bge_S:
            {
                _Convert1by1(VM.OpCode.GTE, src, to);
                var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.tokenAddr_Index;
            }
            break;

            case CodeEx.Bge_Un:
            case CodeEx.Bge_Un_S:
            {
                _Convert1by1(VM.OpCode.ABS, src, to);
                _Convert1by1(VM.OpCode.SWAP, null, to);
                _Convert1by1(VM.OpCode.ABS, null, to);
                _Convert1by1(VM.OpCode.SWAP, null, to);
                _Convert1by1(VM.OpCode.GTE, null, to);
                var code = _Convert1by1(VM.OpCode.JMPIF, null, to, new byte[] { 0, 0 });
                code.needfix = true;
                code.srcaddr = src.tokenAddr_Index;
            }
            break;

            //Stack
            case CodeEx.Dup:
                _Convert1by1(VM.OpCode.DUP, src, to);
                break;

            //Bitwise logic
            case CodeEx.And:
                _Convert1by1(VM.OpCode.AND, src, to);
                break;

            case CodeEx.Or:
                _Convert1by1(VM.OpCode.OR, src, to);
                break;

            case CodeEx.Xor:
                _Convert1by1(VM.OpCode.XOR, src, to);
                break;

            case CodeEx.Not:
                _Convert1by1(VM.OpCode.INVERT, src, to);
                break;

            //math
            case CodeEx.Add:
            case CodeEx.Add_Ovf:
            case CodeEx.Add_Ovf_Un:
                _Convert1by1(VM.OpCode.ADD, src, to);
                break;

            case CodeEx.Sub:
            case CodeEx.Sub_Ovf:
            case CodeEx.Sub_Ovf_Un:
                _Convert1by1(VM.OpCode.SUB, src, to);
                break;

            case CodeEx.Mul:
            case CodeEx.Mul_Ovf:
            case CodeEx.Mul_Ovf_Un:
                _Convert1by1(VM.OpCode.MUL, src, to);
                break;

            case CodeEx.Div:
            case CodeEx.Div_Un:
                _Convert1by1(VM.OpCode.DIV, src, to);
                break;

            case CodeEx.Rem:
            case CodeEx.Rem_Un:
                _Convert1by1(VM.OpCode.MOD, src, to);
                break;

            case CodeEx.Neg:
                _Convert1by1(VM.OpCode.NEGATE, src, to);
                break;

            case CodeEx.Shl:
                _Convert1by1(VM.OpCode.SHL, src, to);
                break;

            case CodeEx.Shr:
            case CodeEx.Shr_Un:
                _Convert1by1(VM.OpCode.SHR, src, to);
                break;

            //logic
            case CodeEx.Clt:
            case CodeEx.Clt_Un:
                _Convert1by1(VM.OpCode.LT, src, to);
                break;

            case CodeEx.Cgt:
            case CodeEx.Cgt_Un:
                _Convert1by1(VM.OpCode.GT, src, to);
                break;

            case CodeEx.Ceq:
                _Convert1by1(VM.OpCode.NUMEQUAL, src, to);
                break;

            //call
            case CodeEx.Call:
            case CodeEx.Callvirt:
                _ConvertCall(src, to);
                break;

            //用上一个参数作为数量,new 一个数组
            case CodeEx.Newarr:
                skipcount = _ConvertNewArr(method, src, to);
                break;


            //array
            case CodeEx.Ldelem_U1:    //用意为byte[] 取一部分.....
                _ConvertPush(1, src, to);
                _Convert1by1(VM.OpCode.SUBSTR, null, to);
                break;

            case CodeEx.Ldelem_Any:
            case CodeEx.Ldelem_I:
            case CodeEx.Ldelem_I1:
            case CodeEx.Ldelem_I2:
            case CodeEx.Ldelem_I4:
            case CodeEx.Ldelem_I8:
            case CodeEx.Ldelem_R4:
            case CodeEx.Ldelem_R8:
            case CodeEx.Ldelem_Ref:
            case CodeEx.Ldelem_U2:
            case CodeEx.Ldelem_U4:
                _Convert1by1(VM.OpCode.PICKITEM, src, to);
                break;

            case CodeEx.Ldlen:
                _Convert1by1(VM.OpCode.ARRAYSIZE, src, to);
                break;

            case CodeEx.Stelem_Any:
            case CodeEx.Stelem_I:
            case CodeEx.Stelem_I1:
            case CodeEx.Stelem_I2:
            case CodeEx.Stelem_I4:
            case CodeEx.Stelem_I8:
            case CodeEx.Stelem_R4:
            case CodeEx.Stelem_R8:
            case CodeEx.Stelem_Ref:
                _Convert1by1(VM.OpCode.SETITEM, src, to);
                break;

            case CodeEx.Castclass:
                break;

            case CodeEx.Box:
            case CodeEx.Unbox:
            case CodeEx.Unbox_Any:
            case CodeEx.Break:
            //也有可能以后利用这个断点调试
            case CodeEx.Conv_I:
            case CodeEx.Conv_I1:
            case CodeEx.Conv_I2:
            case CodeEx.Conv_I4:
            case CodeEx.Conv_I8:
            case CodeEx.Conv_Ovf_I:
            case CodeEx.Conv_Ovf_I_Un:
            case CodeEx.Conv_Ovf_I1:
            case CodeEx.Conv_Ovf_I1_Un:
            case CodeEx.Conv_Ovf_I2:
            case CodeEx.Conv_Ovf_I2_Un:
            case CodeEx.Conv_Ovf_I4:
            case CodeEx.Conv_Ovf_I4_Un:
            case CodeEx.Conv_Ovf_I8:
            case CodeEx.Conv_Ovf_I8_Un:
            case CodeEx.Conv_Ovf_U:
            case CodeEx.Conv_Ovf_U_Un:
            case CodeEx.Conv_Ovf_U1:
            case CodeEx.Conv_Ovf_U1_Un:
            case CodeEx.Conv_Ovf_U2:
            case CodeEx.Conv_Ovf_U2_Un:
            case CodeEx.Conv_Ovf_U4:
            case CodeEx.Conv_Ovf_U4_Un:
            case CodeEx.Conv_Ovf_U8:
            case CodeEx.Conv_Ovf_U8_Un:
            case CodeEx.Conv_U:
            case CodeEx.Conv_U1:
            case CodeEx.Conv_U2:
            case CodeEx.Conv_U4:
            case CodeEx.Conv_U8:
                break;

            ///////////////////////////////////////////////
            //以下因为支持结构体而出现
            //加载一个引用,这里改为加载一个pos值
            case CodeEx.Ldloca:
            case CodeEx.Ldloca_S:
                _ConvertLdLocA(method, src, to, src.tokenI32);
                break;

            case CodeEx.Initobj:
                _ConvertInitObj(src, to);
                break;

            case CodeEx.Newobj:
                _ConvertNewObj(src, to);
                break;

            case CodeEx.Stfld:
                _ConvertStfld(method, src, to);
                break;

            case CodeEx.Ldfld:
                _ConvertLdfld(src, to);
                break;

            case CodeEx.Ldsfld:

            {
                var d = src.tokenUnknown as Mono.Cecil.FieldDefinition;
                //如果是readonly,可以pull个常量上来的
                if (
                    ((d.Attributes & Mono.Cecil.FieldAttributes.InitOnly) > 0) &&
                    ((d.Attributes & Mono.Cecil.FieldAttributes.Static) > 0)
                    )
                {
                    var fname = d.DeclaringType.FullName + "::" + d.Name;
                    var _src  = outModule.staticfields[fname];
                    if (_src is byte[])
                    {
                        var bytesrc = (byte[])_src;
                        _ConvertPush(bytesrc, src, to);
                    }
                    else if (_src is int)
                    {
                        var intsrc = (int)_src;
                        _ConvertPush(intsrc, src, to);
                    }
                    else if (_src is Boolean)
                    {
                        var bsrc = (Boolean)_src;
                        _ConvertPush(bsrc ? 1 : 0, src, to);
                    }
                    else if (_src is string)
                    {
                        var bytesrc = System.Text.Encoding.UTF8.GetBytes((string)_src);
                        _ConvertPush(bytesrc, src, to);
                    }
                    else
                    {
                        throw new Exception("not support type Ldsfld\r\n   in: " + to.name + "\r\n");
                    }
                    break;
                }


                //如果是调用event导致的这个代码,只找出他的名字
                if (d.DeclaringType.HasEvents)
                {
                    foreach (var ev in d.DeclaringType.Events)
                    {
                        if (ev.Name == d.Name && ev.EventType.FullName == d.FieldType.FullName)
                        {
                            Mono.Collections.Generic.Collection <Mono.Cecil.CustomAttribute> ca = ev.CustomAttributes;
                            to.lastsfieldname = d.Name;
                            foreach (var attr in ca)
                            {
                                if (attr.AttributeType.Name == "DisplayNameAttribute")
                                {
                                    to.lastsfieldname = (string)attr.ConstructorArguments[0].Value;
                                }
                            }
                            break;
                        }
                    }
                }
            }
            break;

            case CodeEx.Throw:
            {
                _Convert1by1(VM.OpCode.THROW, src, to);        //throw 会让vm 挂起
                //不需要再插入return
                //_Insert1(VM.OpCode.RET, "", to);
            }
            break;

            default:
#if WITHPDB
                logger.Log("unsupported instruction " + src.code + "\r\n   in: " + to.name + "\r\n");
                break;
#else
                throw new Exception("unsupported instruction " + src.code + "\r\n   in: " + to.name + "\r\n");
#endif
            }

            return(skipcount);
        }
Exemplo n.º 27
0
        public NeoModule Convert(ILModule _in, ConvOption option = null)
        {
            this.inModule = _in;
            //logger.Log("beginConvert.");
            this.outModule        = new NeoModule(this.logger);
            this.outModule.option = option == null ? ConvOption.Default : option;
            foreach (var t in _in.mapType)
            {
                if (t.Key.Contains("<"))
                {
                    continue;//系统的,不要
                }
                if (t.Key.Contains("_API_"))
                {
                    continue;                         //api的,不要
                }
                if (t.Key.Contains(".My."))
                {
                    continue;//vb system
                }
                foreach (var m in t.Value.methods)
                {
                    if (m.Value.method == null)
                    {
                        continue;
                    }
                    if (m.Value.method.IsAddOn || m.Value.method.IsRemoveOn)
                    {
                        continue;//event 自动生成的代码,不要
                    }
                    NeoMethod nm = new NeoMethod();
                    if (m.Key.Contains(".cctor"))
                    {
                        CctorSubVM.Parse(m.Value, this.outModule);
                        continue;
                    }
                    if (m.Value.method.IsConstructor)
                    {
                        continue;
                    }
                    nm._namespace  = m.Value.method.DeclaringType.FullName;
                    nm.name        = m.Value.method.FullName;
                    nm.displayName = m.Value.method.Name;

                    Mono.Collections.Generic.Collection <Mono.Cecil.CustomAttribute> ca = m.Value.method.CustomAttributes;
                    foreach (var attr in ca)
                    {
                        if (attr.AttributeType.Name == "DisplayNameAttribute")
                        {
                            nm.displayName = (string)attr.ConstructorArguments[0].Value;
                        }
                    }
                    nm.inSmartContract            = m.Value.method.DeclaringType.BaseType.Name == "SmartContract";
                    nm.isPublic                   = m.Value.method.IsPublic;
                    this.methodLink[m.Value]      = nm;
                    outModule.mapMethods[nm.name] = nm;
                }
                foreach (var e in t.Value.fields)
                {
                    if (e.Value.isEvent)
                    {
                        NeoEvent ae = new NeoEvent();
                        ae._namespace  = e.Value.field.DeclaringType.FullName;
                        ae.name        = ae._namespace + "::" + e.Key;
                        ae.displayName = e.Value.displayName;
                        ae.returntype  = e.Value.returntype;
                        ae.paramtypes  = e.Value.paramtypes;
                        outModule.mapEvents[ae.name] = ae;
                    }
                }
            }

            var keys = new List <string>(_in.mapType.Keys);

            foreach (var key in keys)
            {
                var value = _in.mapType[key];
                if (key.Contains("<"))
                {
                    continue;//系统的,不要
                }
                if (key.Contains("_API_"))
                {
                    continue;                       //api的,不要
                }
                if (key.Contains(".My."))
                {
                    continue;//vb system
                }
                foreach (var m in value.methods)
                {
                    if (m.Value.method == null)
                    {
                        continue;
                    }
                    if (m.Key.Contains(".cctor"))
                    {
                        continue;
                    }
                    if (m.Value.method.IsAddOn || m.Value.method.IsRemoveOn)
                    {
                        continue;//event 自动生成的代码,不要
                    }
                    var nm = this.methodLink[m.Value];


                    //try
                    {
                        nm.returntype = m.Value.returntype;
                        try
                        {
                            var type = m.Value.method.ReturnType.Resolve();
                            foreach (var i in type.Interfaces)
                            {
                                if (i.InterfaceType.Name == "IApiInterface")
                                {
                                    nm.returntype = "IInteropInterface";
                                }
                            }
                        }
                        catch (Exception err)
                        {
                        }

                        foreach (var src in m.Value.paramtypes)
                        {
                            nm.paramtypes.Add(new NeoParam(src.name, src.type));
                        }

                        byte[] outcall; string name; VM.OpCode[] opcodes; string[] opdata;
                        if (IsAppCall(m.Value.method, out outcall))
                        {
                            continue;
                        }
                        if (IsNonCall(m.Value.method))
                        {
                            continue;
                        }
                        if (IsMixAttribute(m.Value.method, out opcodes, out opdata))
                        {
                            continue;
                        }

                        this.ConvertMethod(m.Value, nm);
                    }
                    //catch (Exception err)
                    //{
                    //    logger.Log("error:" + err.Message);
                    //}
                }
            }
            //转换完了,做个link,全部拼到一起
            string mainmethod = "";

            foreach (var key in outModule.mapMethods.Keys)
            {
                if (key.Contains("::Main("))
                {
                    NeoMethod m = outModule.mapMethods[key];
                    if (m.inSmartContract)
                    {
                        foreach (var l in this.methodLink)
                        {
                            if (l.Value == m)
                            {
                                if (mainmethod != "")
                                {
                                    throw new Exception("Have too mush EntryPoint,Check it.");
                                }
                                mainmethod = key;
                            }
                        }
                    }
                }
            }
            if (mainmethod == "")
            {
                throw new Exception("Can't find EntryPoint,Check it.");
            }
            else
            {
                //单一默认入口
                logger.Log("Find entrypoint:" + mainmethod);
            }

            outModule.mainMethod = mainmethod;
            this.LinkCode(mainmethod);
            //this.findFirstFunc();//得找到第一个函数
            //然后给每个method 分配一个func addr
            //还需要对所有的call 做一次地址转换

            //this.outModule.Build();
            return(outModule);
        }
Exemplo n.º 28
0
        private int _ConvertNewArr(ILMethod method, OpCode src, NeoMethod to)
        {
            var type = src.tokenType;

            if (type != "System.Byte")
            {
                _Convert1by1(VM.OpCode.NEWARRAY, src, to);
                int n  = method.GetNextCodeAddr(src.addr);
                int n2 = method.GetNextCodeAddr(n);
                int n3 = method.GetNextCodeAddr(n2);
                if (n >= 0 && n2 >= 0 && n3 >= 0 && method.body_Codes[n].code == CodeEx.Dup && method.body_Codes[n2].code == CodeEx.Ldtoken && method.body_Codes[n3].code == CodeEx.Call)
                {//這是在初始化數組
                    var data = method.body_Codes[n2].tokenUnknown as byte[];
                    if (type == "System.Char")
                    {
                        for (var i = 0; i < data.Length; i += 2)
                        {
                            char info = BitConverter.ToChar(data, i);
                            _Convert1by1(VM.OpCode.DUP, null, to);
                            _ConvertPush(i / 2, null, to);
                            _ConvertPush(info, null, to);
                            _Convert1by1(VM.OpCode.SETITEM, null, to);
                        }
                        return(3);
                    }
                    throw new Exception("not support this type's init array.");
                }
                return(0);
                //this.logger.Log("_ConvertNewArr::not support type " + type + " for array.");
            }
            else
            {
                var code = to.body_Codes.Last().Value;
                //we need a number
                if (code.code > VM.OpCode.PUSH16)
                {
                    throw new Exception("_ConvertNewArr::not support var lens for new byte[?].");
                }
                var number = getNumber(code);

                //移除上一条指令
                to.body_Codes.Remove(code.addr);
                this.addr = code.addr;
                if (code.bytes != null)
                {
                    this.addr -= code.bytes.Length;
                }

                int n  = method.GetNextCodeAddr(src.addr);
                int n2 = method.GetNextCodeAddr(n);
                int n3 = method.GetNextCodeAddr(n2);
                if (n >= 0 && n2 >= 0 && n3 >= 0 && method.body_Codes[n].code == CodeEx.Dup && method.body_Codes[n2].code == CodeEx.Ldtoken && method.body_Codes[n3].code == CodeEx.Call)
                {//這是在初始化數組
                    var data = method.body_Codes[n2].tokenUnknown as byte[];
                    this._ConvertPush(data, src, to);

                    return(3);
                }
                else
                {
                    this._ConvertPush(new byte[number], src, to);
                }
            }



            return(0);
        }