示例#1
0
        public (int high, int low) Run()
        {
            int ip = 0;
            int sp = 0;

            int[] stack  = new int[MaxStack];
            int[] locals = new int[MaxLocals];

            void Push(int value) => stack[sp++] = value;

            void PushLongFromInts(int high, int low)
            {
                Push(high); Push(low);
            }

            void PushLongFromLong(long value)
            {
                (var high, var low) = value;
                Push(high);
                Push(low);
            }

            int Pop() => stack[--sp];
            (int high, int low) PopLong() => (Pop(), Pop());

            while (true)
            {
                byte opCode = ByteCode[ip];
                switch (opCode)
                {
                case 0x00:
                    break;

                case 0x02:
                case 0x03:
                case 0x04:
                case 0x05:
                case 0x06:
                case 0x07:
                case 0x08:
                    Push(opCode - 0x03);
                    break;

                case 0x1A:
                case 0x1B:
                case 0x1C:
                case 0x1D:
                    Push(locals[opCode - 0x1A]);
                    break;

                case 0x3B:
                case 0x3C:
                case 0x3D:
                case 0x3E:
                    locals[opCode - 0x3B] = Pop();
                    break;

                case 0x60:

                    break;

                case 0xAC:
                    return(0, Pop());

                case 0xB8:


                    int methodrefIndex = (ByteCode[++ip] << 8) + ByteCode[++ip];

                    MethodrefInfo methodref = classFile.PoolInfos[methodrefIndex] as MethodrefInfo;
                    MethodInfo    method    = null;

                    for (int i = 0; i < classFile.Methods.Length; i++)
                    {
                        if (classFile.Methods[i].Name == methodref.RefName)
                        {
                            method = classFile.Methods[i];
                            break;
                        }
                    }

                    //method

                    //method?.Frame.Run();

                    break;

                default:
                    throw new NotImplementedException("Unimplemented Op Code: 0x" + ByteCode[ip].ToString("X2"));
                }
                ip++;
            }
        }
示例#2
0
        private ConstantPoolInfo[] ParseConstantPool(ref ReadOnlySpan <byte> fileData)
        {
            ushort poolCount = fileData.ReadTwoBytes();

            var infos = new ConstantPoolInfo[poolCount];

            for (int i = 1; i < poolCount; i++)
            {
                var tag = (ConstantPoolTag)fileData.ReadOneByte();
                switch (tag)
                {
                case ConstantPoolTag.Class:
                    infos[i] = new ClassInfo(ref fileData);
                    break;

                case ConstantPoolTag.Fieldref:
                    infos[i] = new FieldrefInfo(ref fileData);
                    break;

                case ConstantPoolTag.Methodref:
                    infos[i] = new MethodrefInfo(ref fileData);
                    break;

                case ConstantPoolTag.InterfaceMethodref:
                    infos[i] = new InterfaceMethodrefInfo(ref fileData);
                    break;

                case ConstantPoolTag.String:
                    infos[i] = new StringInfo(ref fileData);
                    break;

                case ConstantPoolTag.Integer:
                    infos[i] = new IntegerInfo(ref fileData);
                    break;

                case ConstantPoolTag.Float:
                    infos[i] = new FloatInfo(ref fileData);
                    break;

                case ConstantPoolTag.Long:
                    infos[i] = new LongInfo(ref fileData);
                    i++;
                    break;

                case ConstantPoolTag.Double:
                    infos[i] = new DoubleInfo(ref fileData);
                    i++;
                    break;

                case ConstantPoolTag.NameAndType:
                    infos[i] = new NameAndTypeInfo(ref fileData);
                    break;

                case ConstantPoolTag.Utf8:
                    infos[i] = new Utf8Info(ref fileData);
                    break;

                case ConstantPoolTag.MethodHandle:
                    fileData.ReadOneByte();
                    fileData.ReadTwoBytes();
                    break;

                case ConstantPoolTag.MethodType:
                    fileData.ReadTwoBytes();
                    break;

                case ConstantPoolTag.InvokeDynamic:
                    fileData.ReadFourBytes();
                    break;

                default:
                    throw new InvalidDataException();
                }
            }

            foreach (ConstantPoolInfo info in infos)
            {
                info?.Init(infos);
            }

            return(infos);
        }