public void Write(JavaWriter wtr, JavaAttribute.Code codeAttr) { wtr.Where.Push("method body"); int codeLength = FillInstructions(wtr); if (codeLength > 0xFFFE) { throw wtr.Where.Exception("output method is too large"); } var labelToOffsetMap = FillJumpTargets(wtr); codeAttr.code = new byte[codeLength]; FillCodeAttr(codeAttr.code); codeAttr.maxStack = (ushort)MaxStack; codeAttr.maxLocals = (ushort)MaxLocals; WriteExceptionData(codeAttr, labelToOffsetMap); if (StackMap != null) { var attr = StackMap.ToAttribute(wtr, labelToOffsetMap); if (attr != null) { codeAttr.attributes.Put(attr); } } if (DebugLocals != null) { var attr = new JavaAttribute.LocalVariableTable(DebugLocals, codeLength); codeAttr.attributes.Put(attr); } FillLineNumbers(codeAttr); wtr.Where.Pop(); }
public JavaAttributeSet(JavaReader rdr, bool withCode = true) { var count = rdr.Read16(); set = new List <JavaAttribute>(count); for (int i = 0; i < count; i++) { var name = rdr.ConstUtf8(rdr.Read16()); rdr.Where.Push($"attribute '{name}'"); bool popped = false; var length = JavaAttribute.ReadLength(rdr, name); var position = rdr.StreamPosition; JavaAttribute attr; switch (name) { case JavaAttribute.SourceFile.tag: attr = new JavaAttribute.SourceFile(rdr); break; case JavaAttribute.Signature.tag: attr = new JavaAttribute.Signature(rdr); break; case JavaAttribute.Exceptions.tag: attr = new JavaAttribute.Exceptions(rdr); break; case JavaAttribute.InnerClasses.tag: attr = new JavaAttribute.InnerClasses(rdr); break; case JavaAttribute.EnclosingMethod.tag: attr = new JavaAttribute.EnclosingMethod(rdr); break; case JavaAttribute.ConstantValue.tag: attr = new JavaAttribute.ConstantValue(rdr); break; case JavaAttribute.MethodParameters.tag: attr = new JavaAttribute.MethodParameters(rdr); break; // // Code attributes // case JavaAttribute.Code.tag: attr = withCode ? (JavaAttribute) new JavaAttribute.Code(rdr) : (JavaAttribute) new JavaAttribute.Generic(rdr, name, length); break; case JavaAttribute.BootstrapMethods.tag: attr = withCode ? (JavaAttribute) new JavaAttribute.BootstrapMethods(rdr) : (JavaAttribute) new JavaAttribute.Generic(rdr, name, length); break; case JavaAttribute.StackMapTable.tag: attr = new JavaAttribute.StackMapTable(rdr); break; case JavaAttribute.LineNumberTable.tag: attr = new JavaAttribute.LineNumberTable(rdr); break; case JavaAttribute.LocalVariableTable.tag: attr = new JavaAttribute.LocalVariableTable(rdr); break; // // Unhandled attributes // case "Synthetic": case "AnnotationDefault": case "LocalVariableTypeTable": case "RuntimeVisibleAnnotations": case "RuntimeInvisibleAnnotations": case "RuntimeInvisibleParameterAnnotations": case "Deprecated": attr = new JavaAttribute.Generic(rdr, name, length); break; default: rdr.Where.Pop(); popped = true; Console.WriteLine($"skipping unknown attribute '{name}'{rdr.Where}"); attr = new JavaAttribute.Generic(rdr, name, length); break; } set.Add(attr); if (rdr.StreamPosition != position + length) { throw rdr.Where.Exception("attribute too short"); } if (!popped) { rdr.Where.Pop(); } } }