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++; } }
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); }