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);
        }
示例#2
0
        /// <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;
                }
            }
        }