public CodeAttribute Serialize(BuildingContext context) { // Verify stack. if (ComputeMaxStackOnBuild) { MaxStack = ComputeMaxStack(); } // Code. var result = new CodeAttribute { Code = GenerateRawCode(context), MaxStack = (ushort)MaxStack, MaxLocals = (ushort)Variables.Count }; // Exception handlers. foreach (var info in GenerateExceptionHandlerInfos(context)) { result.ExceptionHandlers.Add(info); } // Variables. if (Variables.Count > 0) { var localsAttribute = new LocalVariableTableAttribute(); foreach (var variable in Variables) { localsAttribute.LocalVariables.Add(new LocalVariableInfo { StartOffset = (ushort)variable.Start.Offset, Length = (ushort)((variable.End?.Offset ?? result.Code.Length) - variable.Start.Offset), NameIndex = (ushort)context.Builder.ConstantPoolBuffer.GetUtf8Index(variable.Name), DescriptorIndex = (ushort)context.Builder.ConstantPoolBuffer.GetDescriptorIndex(variable.Descriptor), LocalIndex = (ushort)variable.Index, }); } result.Attributes.Add(context.Builder.CreateAttribute(context, localsAttribute)); } // Additional attributes. context.Builder.AddAttributes(context, result, this); return(result); }
/// <summary> /// Read a LocalVariableTable attribute /// </summary> private LocalVariableTableAttribute ReadLocalVariableTableAttribute(ConstantPool cp) { var result = new LocalVariableTableAttribute(); var count = stream.ReadU2(); for (var i = 0; i < count; i++) { var startPC = stream.ReadU2(); var length = stream.ReadU2(); var nameIndex = stream.ReadU2(); var name = cp.GetEntry <ConstantPoolUtf8>(nameIndex).Value; var descriptorIndex = stream.ReadU2(); var descriptor = cp.GetEntry <ConstantPoolUtf8>(descriptorIndex).Value; var variableType = Descriptors.ParseFieldType(descriptor); var index = stream.ReadU2(); result.Variables.Add(new LocalVariable(startPC, length, name, variableType, index)); } return(result); }
internal ByteCodeMethodBody(JavaClassImage classImage, CodeAttribute attribute) { MaxStack = attribute.MaxStack; // Read instructions. var disassembler = new ByteCodeDisassembler(new MemoryBigEndianReader(attribute.Code)) { OperandResolver = new DefaultOperandResolver(classImage) }; foreach (var instruction in disassembler.ReadInstructions()) { Instructions.Add(instruction); } // Read exception handlers. foreach (var handler in attribute.ExceptionHandlers) { ExceptionHandlers.Add(new ExceptionHandler(classImage, this, handler)); } // Read attributes. foreach (var attr in attribute.Attributes) { string name = classImage.ClassFile.ConstantPool.ResolveString(attr.NameIndex); switch (name) { // Local variables case LocalVariableTableAttribute.AttributeName: var localsTable = LocalVariableTableAttribute.FromReader(new MemoryBigEndianReader(attr.Contents)); foreach (var info in localsTable.LocalVariables) { Variables.Add(new LocalVariable(classImage, this, info)); } break; default: ExtraAttributes.Add(name, attr.Clone()); break; } } }