[Ikvm-commit] ikvm/runtime/stubgen ClassFileWriter.cs, 1.9, 1.10 StubGenerator.cs, 1.12, 1.13
Brought to you by:
jfrijters
|
From: Jeroen F. <jfr...@us...> - 2014-06-06 09:04:19
|
Update of /cvsroot/ikvm/ikvm/runtime/stubgen In directory sfp-cvs-1.v30.ch3.sourceforge.com:/tmp/cvs-serv28391 Modified Files: ClassFileWriter.cs StubGenerator.cs Log Message: Implemented (runtime visible) type annotation rendering in runtime stub generator. Index: StubGenerator.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/stubgen/StubGenerator.cs,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** StubGenerator.cs 3 Jun 2014 12:04:42 -0000 1.12 --- StubGenerator.cs 6 Jun 2014 09:04:17 -0000 1.13 *************** *** 94,97 **** --- 94,98 ---- } AddAnnotations(writer, writer, tw.TypeAsBaseType); + AddTypeAnnotations(writer, writer, tw, tw.GetRawTypeAnnotations()); writer.AddStringAttribute("IKVM.NET.Assembly", GetAssemblyName(tw)); if (tw.TypeAsBaseType.IsDefined(JVM.Import(typeof(ObsoleteAttribute)), false)) *************** *** 220,223 **** --- 221,225 ---- AddAnnotations(writer, m, mw.GetMethod()); AddParameterAnnotations(writer, m, mw.GetMethod()); + AddTypeAnnotations(writer, m, tw, tw.GetMethodRawTypeAnnotations(mw)); } } *************** *** 251,254 **** --- 253,257 ---- } AddAnnotations(writer, f, fw.GetField()); + AddTypeAnnotations(writer, f, tw, tw.GetFieldRawTypeAnnotations(fw)); } } *************** *** 333,336 **** --- 336,476 ---- } + private static void AddTypeAnnotations(ClassFileWriter writer, IAttributeOwner target, TypeWrapper tw, byte[] typeAnnotations) + { + #if !FIRST_PASS && !STUB_GENERATOR + if (typeAnnotations != null) + { + typeAnnotations = (byte[])typeAnnotations.Clone(); + object[] constantPool = tw.GetConstantPool(); + try + { + int pos = 0; + ushort num_annotations = ReadUInt16BE(typeAnnotations, ref pos); + for (int i = 0; i < num_annotations; i++) + { + FixupTypeAnnotationConstantPoolIndexes(writer, typeAnnotations, constantPool, ref pos); + } + } + catch (IndexOutOfRangeException) + { + // if the attribute is malformed, we add it anyway and hope the Java parser will agree and throw the right error + } + target.AddAttribute(new RuntimeVisibleTypeAnnotationsAttribute(writer, typeAnnotations)); + } + #endif + } + + private static void FixupTypeAnnotationConstantPoolIndexes(ClassFileWriter writer, byte[] typeAnnotations, object[] constantPool, ref int pos) + { + switch (typeAnnotations[pos++]) // target_type + { + case 0x00: + case 0x01: + case 0x16: + pos++; + break; + case 0x10: + case 0x11: + case 0x12: + case 0x17: + pos += 2; + break; + case 0x13: + case 0x14: + case 0x15: + break; + default: + throw new IndexOutOfRangeException(); + } + byte path_length = typeAnnotations[pos++]; + pos += path_length * 2; + FixupAnnotationConstantPoolIndexes(writer, typeAnnotations, constantPool, ref pos); + } + + private static void FixupAnnotationConstantPoolIndexes(ClassFileWriter writer, byte[] typeAnnotations, object[] constantPool, ref int pos) + { + FixupConstantPoolIndex(writer, typeAnnotations, constantPool, ref pos); + ushort num_components = ReadUInt16BE(typeAnnotations, ref pos); + for (int i = 0; i < num_components; i++) + { + FixupConstantPoolIndex(writer, typeAnnotations, constantPool, ref pos); + FixupAnnotationComponentValueConstantPoolIndexes(writer, typeAnnotations, constantPool, ref pos); + } + } + + private static void FixupConstantPoolIndex(ClassFileWriter writer, byte[] typeAnnotations, object[] constantPool, ref int pos) + { + ushort index = ReadUInt16BE(typeAnnotations, ref pos); + object item = constantPool[index]; + if (item is int) + { + index = writer.AddInt((int)item); + } + else if (item is long) + { + index = writer.AddLong((long)item); + } + else if (item is float) + { + index = writer.AddFloat((float)item); + } + else if (item is double) + { + index = writer.AddDouble((double)item); + } + else if (item is string) + { + index = writer.AddUtf8((string)item); + } + else + { + throw new IndexOutOfRangeException(); + } + typeAnnotations[pos - 2] = (byte)(index >> 8); + typeAnnotations[pos - 1] = (byte)(index >> 0); + } + + private static void FixupAnnotationComponentValueConstantPoolIndexes(ClassFileWriter writer, byte[] typeAnnotations, object[] constantPool, ref int pos) + { + switch ((char)typeAnnotations[pos++]) // tag + { + case 'B': + case 'C': + case 'D': + case 'F': + case 'I': + case 'J': + case 'S': + case 'Z': + case 's': + case 'c': + FixupConstantPoolIndex(writer, typeAnnotations, constantPool, ref pos); + break; + case 'e': + FixupConstantPoolIndex(writer, typeAnnotations, constantPool, ref pos); + FixupConstantPoolIndex(writer, typeAnnotations, constantPool, ref pos); + break; + case '@': + FixupAnnotationConstantPoolIndexes(writer, typeAnnotations, constantPool, ref pos); + break; + case '[': + ushort num_values = ReadUInt16BE(typeAnnotations, ref pos); + for (int i = 0; i < num_values; i++) + { + FixupAnnotationComponentValueConstantPoolIndexes(writer, typeAnnotations, constantPool, ref pos); + } + break; + default: + throw new IndexOutOfRangeException(); + } + } + + private static ushort ReadUInt16BE(byte[] buf, ref int pos) + { + ushort s = (ushort)((buf[pos] << 8) + buf[pos + 1]); + pos += 2; + return s; + } + #if !FIRST_PASS && !STUB_GENERATOR private static object[] GetAnnotation(CustomAttributeData cad) Index: ClassFileWriter.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/stubgen/ClassFileWriter.cs,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** ClassFileWriter.cs 3 Jun 2014 12:04:42 -0000 1.9 --- ClassFileWriter.cs 6 Jun 2014 09:04:17 -0000 1.10 *************** *** 73,76 **** --- 73,81 ---- } + public void WriteBytes(byte[] data) + { + stream.Write(data, 0, data.Length); + } + public void WriteUtf8(string str) { *************** *** 729,732 **** --- 734,755 ---- } + sealed class RuntimeVisibleTypeAnnotationsAttribute : ClassFileAttribute + { + private readonly byte[] data; + + internal RuntimeVisibleTypeAnnotationsAttribute(ClassFileWriter classFile, byte[] data) + : base(classFile.AddUtf8("RuntimeVisibleTypeAnnotations")) + { + this.data = data; + } + + public override void Write(BigEndianStream bes) + { + base.Write(bes); + bes.WriteUInt32((uint)data.Length); + bes.WriteBytes(data); + } + } + sealed class AnnotationDefaultClassFileAttribute : ClassFileAttribute { |