public static ConstantPool ReadConstantPool(BytecodeReader reader, ushort constantPoolCount) { // TODO: check if long and double constants reading right ConstantPool constantPool = new ConstantPool(); int a = 0; var tagDictionary = new Dictionary <int, Action>(); tagDictionary.Add(1, () => { ushort length = reader.ReadUShort(); String value = reader.ReadString(length); constantPool.AddConstantUtf8(new ConstantUtf8(length, value)); }); tagDictionary.Add(3, () => constantPool.AddConstantInteger(reader.ReadInt())); tagDictionary.Add(4, () => constantPool.AddConstantFloat(reader.ReadFloat())); tagDictionary.Add(5, () => constantPool.AddConstantLong(reader.ReadLong())); tagDictionary.Add(6, () => constantPool.AddConstantDouble(reader.ReadDouble())); tagDictionary.Add(7, () => constantPool.AddConstantClass(new ConstantClass(reader.ReadUShort()))); tagDictionary.Add(8, () => constantPool.AddConstantString(new ConstantString(reader.ReadUShort()))); tagDictionary.Add(9, () => constantPool.AddConstantFieldRef(new ConstantFieldRef(reader.ReadUShort(), reader.ReadUShort()))); tagDictionary.Add(10, () => constantPool.AddConstantMethodRef(new ConstantMethodRef(reader.ReadUShort(), reader.ReadUShort()))); tagDictionary.Add(11, () => constantPool.AddConstantInterfaceMethodRef(new ConstantInterfaceMethodRef(reader.ReadUShort(), reader.ReadUShort()))); tagDictionary.Add(12, () => constantPool.AddConstantNameAndType(new ConstantNameAndType(reader.ReadUShort(), reader.ReadUShort()))); tagDictionary.Add(15, () => constantPool.AddConstantMethodHandle(new ConstantMethodHandle(reader.ReadByte(), reader.ReadUShort()))); tagDictionary.Add(16, () => constantPool.AddConstantMethodType(new ConstantMethodType(reader.ReadUShort()))); tagDictionary.Add(18, () => constantPool.AddConstantInvokeDynamic(new ConstantInvokeDynamic(reader.ReadUShort(), reader.ReadUShort()))); tagDictionary.Add(19, () => constantPool.AddConstantModule(new ConstantModule(reader.ReadUShort()))); tagDictionary.Add(20, () => constantPool.AddConstantPackage(new ConstantPackage(reader.ReadUShort()))); Action createConstant; for (int i = 0; i < constantPoolCount; i++) { if (tagDictionary.TryGetValue(reader.ReadByte(), out createConstant)) { createConstant.Invoke(); } else { throw new KeyNotFoundException("Constant type not recognized"); } } return(constantPool); }
public static Attributes ReadAttributes(BytecodeReader reader, ushort attributesCount) { Attributes attributes = new Attributes(); Dictionary <String, Action> attributeNameDictionary = new Dictionary <string, Action>(); attributeNameDictionary.Add("Code", () => { ushort attributeNameIndex = reader.ReadUShort(); uint attributeLength = reader.ReadUInt(); ushort maxStack = reader.ReadUShort(); ushort maxLocals = reader.ReadUShort(); uint codeLength = reader.ReadUInt(); byte[] code = reader.ReadBytes(codeLength); ushort exceptionTableLength = reader.ReadUShort(); byte[] exceptionTable = reader.ReadBytes((uint)exceptionTableLength * 8); ushort codeAttributesCount = reader.ReadUShort(); Attributes codeAttributes = ReadAttributes(reader, codeAttributesCount); attributes.AddAttributeCode(attributeNameIndex, attributeLength, maxStack, maxLocals, codeLength, code, exceptionTableLength, exceptionTable, attributesCount, attributes); }); short attributeIndex = 0; var attributesTable = new List <AttributeSuper>(); int curAttributeNameIndex; while (attributesCount > attributeIndex) { curAttributeNameIndex = bytecode[index] * 0x100 + bytecode[index + 1]; switch (cp.getConstantUtf8(curAttributeNameIndex).Value) { case "Code": attributesTable.Add(AttributeCode.Create(bytecode, cp)); attributeIndex++; break; case "ConstantValue": // TODO: not skipping bytes Console.WriteLine("ConstantValue attribute was created"); attributesTable.Add(AttributeSuper.Create(bytecode)); index += (int)attributesTable.Last().AttributeLength; attributeIndex++; break; case "StackMapTable": // TODO: not skipping bytes Console.WriteLine("StackMapTable attribute was created"); attributesTable.Add(AttributeSuper.Create(bytecode)); index += (int)attributesTable.Last().AttributeLength; attributeIndex++; break; case "BootstrapMethods": // TODO: not skipping bytes Console.WriteLine("BootstrapMethods attribute was created"); attributesTable.Add(AttributeSuper.Create(bytecode)); index += (int)attributesTable.Last().AttributeLength; attributeIndex++; break; case "LineNumberTable": attributesTable.Add(AttributeLineNumberTable.Create(bytecode, cp)); attributeIndex++; break; case "SourceFile": attributesTable.Add(AttributeSourceFile.Create(bytecode, cp)); attributeIndex++; break; default: attributeIndex++; Console.WriteLine("no attribute found"); break; } } return(new Attributes(attributesTable)); }