Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/ikvm-fork.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjfrijters <jfrijters>2013-02-21 20:56:08 +0400
committerjfrijters <jfrijters>2013-02-21 20:56:08 +0400
commit4bf1c0dca4e97a229381fd59592a1ce3224ea87a (patch)
tree63be3189e562949ee7d39e2f35f8f1c7caa3ae89
parenta1ba4a280cb24b022833d7cf301c96ce11a8cd89 (diff)
Removed the old Java stub class generator and replaced it with the ikvmstub core.
-rw-r--r--classpath/gnu/java/net/protocol/ikvmres/Handler.java5
-rw-r--r--classpath/ikvm/internal/stubgen/StubGenerator.java1603
-rw-r--r--ikvmstub/ikvmstub.8.csproj5
-rw-r--r--ikvmstub/ikvmstub.build5
-rw-r--r--ikvmstub/ikvmstub.cs460
-rw-r--r--openjdk/allsources.lst1
-rw-r--r--openjdk/response.txt41
-rw-r--r--runtime/IKVM.Runtime.8.csproj3
-rw-r--r--runtime/common.cs10
-rw-r--r--runtime/openjdk.cs1
-rw-r--r--runtime/runtime.build3
-rw-r--r--runtime/stubgen/ClassFileWriter.cs (renamed from ikvmstub/ClassFileWriter.cs)0
-rw-r--r--runtime/stubgen/SerialVersionUID.cs (renamed from ikvmstub/SerialVersionUID.cs)2
-rw-r--r--runtime/stubgen/StubGenerator.cs525
-rw-r--r--runtime/vfs.cs5
15 files changed, 579 insertions, 2090 deletions
diff --git a/classpath/gnu/java/net/protocol/ikvmres/Handler.java b/classpath/gnu/java/net/protocol/ikvmres/Handler.java
index b8d0ae29..e122c484 100644
--- a/classpath/gnu/java/net/protocol/ikvmres/Handler.java
+++ b/classpath/gnu/java/net/protocol/ikvmres/Handler.java
@@ -119,7 +119,7 @@ public class Handler extends URLStreamHandler
try
{
Class c = Class.forName(resource.substring(1, resource.length() - 6).replace('/', '.'), false, loader);
- return new ByteArrayInputStream(ikvm.internal.stubgen.StubGenerator.generateStub(c));
+ return new ByteArrayInputStream(GenerateStub(c));
}
catch(ClassNotFoundException _)
{
@@ -152,7 +152,7 @@ public class Handler extends URLStreamHandler
Class c = LoadClassFromAssembly(asm, resource.substring(1, resource.length() - 6).replace('/', '.'));
if(c != null)
{
- return new ByteArrayInputStream(ikvm.internal.stubgen.StubGenerator.generateStub(c));
+ return new ByteArrayInputStream(GenerateStub(c));
}
}
throw (FileNotFoundException)new FileNotFoundException().initCause(x);
@@ -163,6 +163,7 @@ public class Handler extends URLStreamHandler
}
}
+ private static native byte[] GenerateStub(Class c);
private static native cli.System.IO.Stream ReadResourceFromAssemblyImpl(Assembly asm, String resource);
private static native Class LoadClassFromAssembly(Assembly asm, String className);
private static native Assembly LoadAssembly(String name)
diff --git a/classpath/ikvm/internal/stubgen/StubGenerator.java b/classpath/ikvm/internal/stubgen/StubGenerator.java
deleted file mode 100644
index bfb1eeb5..00000000
--- a/classpath/ikvm/internal/stubgen/StubGenerator.java
+++ /dev/null
@@ -1,1603 +0,0 @@
-/*
- Copyright (C) 2006, 2007 Jeroen Frijters
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- Jeroen Frijters
- jeroen@frijters.net
-
-*/
-
-package ikvm.internal.stubgen;
-
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.io.ObjectStreamClass;
-import java.io.OutputStream;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Array;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Hashtable;
-
-public final class StubGenerator implements PrivilegedAction<byte[]>
-{
- private Class c;
-
- private StubGenerator(Class c)
- {
- this.c = c;
- }
-
- @ikvm.lang.Internal
- public static byte[] generateStub(Class c)
- {
- return AccessController.doPrivileged(new StubGenerator(c));
- }
-
- public byte[] run()
- {
- boolean includeNonPublicInterfaces = !"true".equalsIgnoreCase(System.getProperty("ikvm.stubgen.skipNonPublicInterfaces"));
- Class outer = c.getDeclaringClass();
- String name = c.getName().replace('.', '/');
- String superClass = null;
- if(c.getSuperclass() != null)
- {
- superClass = c.getSuperclass().getName().replace('.', '/');
- }
- if(c.isInterface())
- {
- superClass = "java/lang/Object";
- }
- ClassFileWriter f = new ClassFileWriter(getRealModifiers(c), name, superClass, 0, 49);
- String genericSignature = BuildGenericSignature(c);
- if(genericSignature != null)
- {
- f.AddStringAttribute("Signature", genericSignature);
- }
- f.AddStringAttribute("IKVM.NET.Assembly", getAssemblyName(c));
- if(isClassDeprecated(c))
- {
- f.AddAttribute(new DeprecatedAttribute(f));
- }
- InnerClassesAttribute innerClassesAttribute = null;
- if(outer != null)
- {
- innerClassesAttribute = new InnerClassesAttribute(f);
- String innername = name;
- // TODO instead of mangling the name, maybe we chould use the new Class APIs (e.g. getSimpleName())
- int idx = name.lastIndexOf('$');
- if(idx >= 0)
- {
- innername = innername.substring(idx + 1);
- }
- innerClassesAttribute.Add(name, outer.getName().replace('.', '/'), innername, getModifiers(c));
- }
- Class[] interfaces = c.getInterfaces();
- for(int i = 0; i < interfaces.length; i++)
- {
- if(includeNonPublicInterfaces || Modifier.isPublic(interfaces[i].getModifiers()))
- {
- f.AddInterface(interfaces[i].getName().replace('.', '/'));
- }
- }
- Class[] innerClasses = c.getDeclaredClasses();
- for(int i = 0; i < innerClasses.length; i++)
- {
- // TODO add private export support (for bcel)
- int mods = getModifiers(innerClasses[i]);
- if((mods & (Modifiers.Public | Modifiers.Protected)) != 0)
- {
- if(innerClassesAttribute == null)
- {
- innerClassesAttribute = new InnerClassesAttribute(f);
- }
- String namePart = innerClasses[i].getName();
- // TODO name mangling
- namePart = namePart.substring(namePart.lastIndexOf('$') + 1);
- innerClassesAttribute.Add(innerClasses[i].getName().replace('.', '/'), name, namePart, mods);
- }
- }
- java.lang.reflect.Constructor[] constructors = c.getDeclaredConstructors();
- for(int i = 0; i < constructors.length; i++)
- {
- int mods = constructors[i].getModifiers();
- if((mods & (Modifiers.Public | Modifiers.Protected)) != 0)
- {
- if(constructors[i].isSynthetic())
- {
- mods |= Modifiers.Synthetic;
- }
- if(constructors[i].isVarArgs())
- {
- mods |= Modifiers.VarArgs;
- }
- Class[] args = constructors[i].getParameterTypes();
- FieldOrMethod m = f.AddMethod(mods, "<init>", MakeSig(args, java.lang.Void.TYPE));
- CodeAttribute code = new CodeAttribute(f);
- code.SetMaxLocals(args.length * 2 + 1);
- code.SetMaxStack(3);
- short index1 = f.AddClass("java/lang/UnsatisfiedLinkError");
- short index2 = f.AddString("ikvmstub generated stubs can only be used on IKVM.NET");
- short index3 = f.AddMethodRef("java/lang/UnsatisfiedLinkError", "<init>", "(Ljava/lang/String;)V");
- code.SetByteCode(new byte[]
- {
- (byte)187, (byte)(index1 >> 8), (byte)index1, // new java/lang/UnsatisfiedLinkError
- (byte)89, // dup
- (byte)19, (byte)(index2 >> 8), (byte)index2, // ldc_w "..."
- (byte)183, (byte)(index3 >> 8), (byte)index3, // invokespecial java/lang/UnsatisfiedLinkError/init()V
- (byte)191 // athrow
- });
- m.AddAttribute(code);
- AddExceptions(f, m, constructors[i].getExceptionTypes());
- if(isMethodDeprecated(constructors[i]))
- {
- m.AddAttribute(new DeprecatedAttribute(f));
- }
- String signature = BuildGenericSignature(constructors[i].getTypeParameters(),
- constructors[i].getGenericParameterTypes(), Void.TYPE, constructors[i].getGenericExceptionTypes());
- if (signature != null)
- {
- m.AddAttribute(f.MakeStringAttribute("Signature", signature));
- }
- Annotation[] annotations = constructors[i].getDeclaredAnnotations();
- if(annotations.length > 0)
- {
- m.AddAttribute(new RuntimeVisibleAnnotationsAttribute(f, annotations));
- }
- Annotation[][] parameterAnnotations = constructors[i].getParameterAnnotations();
- if(hasParameterAnnotations(parameterAnnotations))
- {
- m.AddAttribute(new RuntimeVisibleAnnotationsAttribute(f, parameterAnnotations));
- }
- }
- }
- java.lang.reflect.Method[] methods = c.getDeclaredMethods();
- for(int i = 0; i < methods.length; i++)
- {
- int mods = methods[i].getModifiers();
- if((mods & (Modifiers.Public | Modifiers.Protected)) != 0)
- {
- if((mods & Modifiers.Abstract) == 0)
- {
- mods |= Modifiers.Native;
- }
- if(methods[i].isBridge())
- {
- mods |= Modifiers.Bridge;
- }
- if(methods[i].isSynthetic())
- {
- mods |= Modifiers.Synthetic;
- }
- if(methods[i].isVarArgs())
- {
- mods |= Modifiers.VarArgs;
- }
- Class[] args = methods[i].getParameterTypes();
- Class retType = methods[i].getReturnType();
- FieldOrMethod m = f.AddMethod(mods, methods[i].getName(), MakeSig(args, retType));
- AddExceptions(f, m, methods[i].getExceptionTypes());
- if(isMethodDeprecated(methods[i]))
- {
- m.AddAttribute(new DeprecatedAttribute(f));
- }
- String signature = BuildGenericSignature(methods[i].getTypeParameters(),
- methods[i].getGenericParameterTypes(), methods[i].getGenericReturnType(),
- methods[i].getGenericExceptionTypes());
- if (signature != null)
- {
- m.AddAttribute(f.MakeStringAttribute("Signature", signature));
- }
- Object defaultValue = methods[i].getDefaultValue();
- if(defaultValue != null)
- {
- m.AddAttribute(new AnnotationDefaultClassFileAttribute(f, defaultValue));
- }
- Annotation[] annotations = methods[i].getDeclaredAnnotations();
- if(annotations.length > 0)
- {
- m.AddAttribute(new RuntimeVisibleAnnotationsAttribute(f, annotations));
- }
- Annotation[][] parameterAnnotations = methods[i].getParameterAnnotations();
- if(hasParameterAnnotations(parameterAnnotations))
- {
- m.AddAttribute(new RuntimeVisibleAnnotationsAttribute(f, parameterAnnotations));
- }
- }
- }
- java.lang.reflect.Field[] fields = c.getDeclaredFields();
- for(int i = 0; i < fields.length; i++)
- {
- int mods = fields[i].getModifiers();
- if((mods & (Modifiers.Public | Modifiers.Protected)) != 0)
- {
- // NOTE we can't use Field.get() because that will run the static initializer and
- // also won't allow us to see the difference between constants and blank final fields,
- // so we use a "native" method.
- Object constantValue = getFieldConstantValue(fields[i]);
- Class fieldType = fields[i].getType();
- if(fields[i].isEnumConstant())
- {
- mods |= Modifiers.Enum;
- }
- if(fields[i].isSynthetic())
- {
- mods |= Modifiers.Synthetic;
- }
- FieldOrMethod fld = f.AddField(mods, fields[i].getName(), ClassToSig(fieldType), constantValue);
- if(isFieldDeprecated(fields[i]))
- {
- fld.AddAttribute(new DeprecatedAttribute(f));
- }
- if(fields[i].getGenericType() != fieldType)
- {
- fld.AddAttribute(f.MakeStringAttribute("Signature", ToSigForm(fields[i].getGenericType())));
- }
- Annotation[] annotations = fields[i].getDeclaredAnnotations();
- if(annotations.length > 0)
- {
- fld.AddAttribute(new RuntimeVisibleAnnotationsAttribute(f, annotations));
- }
- }
- }
- if(innerClassesAttribute != null)
- {
- f.AddAttribute(innerClassesAttribute);
- }
- Annotation[] annotations = c.getDeclaredAnnotations();
- if(annotations.length > 0)
- {
- f.AddAttribute(new RuntimeVisibleAnnotationsAttribute(f, annotations));
- }
- try
- {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- f.Write(baos);
- return baos.toByteArray();
- }
- catch (IOException x)
- {
- throw new Error(x);
- }
- }
-
- private static boolean hasParameterAnnotations(Annotation[][] parameterAnnotations)
- {
- for(int i = 0; i < parameterAnnotations.length; i++)
- {
- if(parameterAnnotations[i].length > 0)
- {
- return true;
- }
- }
- return false;
- }
-
- private static int getModifiers(Class c)
- {
- int mods = c.getModifiers();
- if(c.isAnnotation())
- {
- mods |= Modifiers.Annotation;
- }
- if(c.isEnum())
- {
- mods |= Modifiers.Enum;
- }
- if(c.isSynthetic())
- {
- mods |= Modifiers.Synthetic;
- }
- return mods;
- }
-
- private static native int getRealModifiers(Class c);
- private static native String getAssemblyName(Class c);
- private static native boolean isClassDeprecated(Class c);
- private static native boolean isFieldDeprecated(Object field);
- private static native boolean isMethodDeprecated(Object method);
- private static native Object getFieldConstantValue(Object field);
-
- private static void AddExceptions(ClassFileWriter f, FieldOrMethod m, Class[] exceptions)
- {
- if (exceptions.length > 0)
- {
- ExceptionsAttribute attrib = new ExceptionsAttribute(f);
- for (int i = 0; i < exceptions.length; i++)
- {
- attrib.Add(exceptions[i].getName().replace('.', '/'));
- }
- m.AddAttribute(attrib);
- }
- }
-
- private static String MakeSig(Class[] args, Class ret)
- {
- StringBuilder sb = new StringBuilder();
- sb.append('(');
- for(int i = 0; i < args.length; i++)
- {
- sb.append(ClassToSig(args[i]));
- }
- sb.append(')');
- sb.append(ClassToSig(ret));
- return sb.toString();
- }
-
- private static String ClassToSig(Class c)
- {
- if(c.isPrimitive())
- {
- if(c == Void.TYPE)
- {
- return "V";
- }
- else if(c == Byte.TYPE)
- {
- return "B";
- }
- else if(c == Boolean.TYPE)
- {
- return "Z";
- }
- else if(c == Short.TYPE)
- {
- return "S";
- }
- else if(c == Character.TYPE)
- {
- return "C";
- }
- else if(c == Integer.TYPE)
- {
- return "I";
- }
- else if(c == Long.TYPE)
- {
- return "J";
- }
- else if(c == Float.TYPE)
- {
- return "F";
- }
- else if(c == Double.TYPE)
- {
- return "D";
- }
- else
- {
- throw new Error();
- }
- }
- else if(c.isArray())
- {
- return "[" + ClassToSig(c.getComponentType());
- }
- else
- {
- return "L" + c.getName().replace('.', '/') + ";";
- }
- }
-
- private static String BuildGenericSignature(Class c)
- {
- boolean isgeneric = false;
- StringBuilder sb = new StringBuilder();
- java.lang.reflect.TypeVariable[] vars = c.getTypeParameters();
- if(vars.length > 0)
- {
- isgeneric = true;
- sb.append('<');
- for (int i = 0; i < vars.length; i++)
- {
- java.lang.reflect.TypeVariable t = vars[i];
- sb.append(t.getName());
- boolean first = true;
- java.lang.reflect.Type[] bounds = t.getBounds();
- for (int j = 0; j < bounds.length; j++)
- {
- java.lang.reflect.Type bound = bounds[j];
- if(first)
- {
- first = false;
- if(bound instanceof Class)
- {
- // HACK I don't really understand what the proper criterion is to decide this
- if(((Class)bound).isInterface())
- {
- sb.append(':');
- }
- }
- }
- sb.append(':').append(ToSigForm(bound));
- }
- }
- sb.append('>');
- }
- java.lang.reflect.Type superclass = c.getGenericSuperclass();
- if(superclass == null)
- {
- sb.append("Ljava/lang/Object;");
- }
- else
- {
- isgeneric |= !(superclass instanceof Class);
- sb.append(ToSigForm(superclass));
- }
- java.lang.reflect.Type[] interfaces = c.getGenericInterfaces();
- for (int i = 0; i < interfaces.length; i++)
- {
- java.lang.reflect.Type t = interfaces[i];
- isgeneric |= !(t instanceof Class);
- sb.append(ToSigForm(t));
- }
- if(isgeneric)
- {
- return sb.toString();
- }
- return null;
- }
-
- private static String BuildGenericSignature(java.lang.reflect.TypeVariable[] typeParameters,
- java.lang.reflect.Type[] parameterTypes, java.lang.reflect.Type returnType,
- java.lang.reflect.Type[] exceptionTypes)
- {
- boolean isgeneric = false;
- StringBuilder sb = new StringBuilder();
- if(typeParameters.length > 0)
- {
- isgeneric = true;
- sb.append('<');
- for (int i = 0; i < typeParameters.length; i++)
- {
- java.lang.reflect.TypeVariable t = typeParameters[i];
- sb.append(t.getName());
- java.lang.reflect.Type[] bounds = t.getBounds();
- for (int j = 0; j < bounds.length; j++)
- {
- sb.append(':').append(ToSigForm(bounds[j]));
- }
- }
- sb.append('>');
- }
- sb.append('(');
- for (int i = 0; i < parameterTypes.length; i++)
- {
- java.lang.reflect.Type t = parameterTypes[i];
- isgeneric |= !(t instanceof Class);
- sb.append(ToSigForm(t));
- }
- sb.append(')');
- sb.append(ToSigForm(returnType));
- isgeneric |= !(returnType instanceof Class);
- for (int i = 0; i < exceptionTypes.length; i++)
- {
- java.lang.reflect.Type t = exceptionTypes[i];
- isgeneric |= !(t instanceof Class);
- sb.append('^').append(ToSigForm(t));
- }
- if(isgeneric)
- {
- return sb.toString();
- }
- return null;
- }
-
- private static String ToSigForm(java.lang.reflect.Type t)
- {
- if(t instanceof java.lang.reflect.ParameterizedType)
- {
- java.lang.reflect.ParameterizedType p = (java.lang.reflect.ParameterizedType)t;
- StringBuilder sb = new StringBuilder();
- sb.append('L').append(((Class)p.getRawType()).getName().replace('.', '/'));
- sb.append('<');
- java.lang.reflect.Type[] args = p.getActualTypeArguments();
- for (int i = 0; i < args.length; i++)
- {
- sb.append(ToSigForm(args[i]));
- }
- sb.append(">;");
- return sb.toString();
- }
- else if(t instanceof java.lang.reflect.TypeVariable)
- {
- return "T" + ((java.lang.reflect.TypeVariable)t).getName() + ";";
- }
- else if(t instanceof java.lang.reflect.WildcardType)
- {
- java.lang.reflect.WildcardType w = (java.lang.reflect.WildcardType)t;
- java.lang.reflect.Type[] lower = w.getLowerBounds();
- java.lang.reflect.Type[] upper = w.getUpperBounds();
- if (lower.length == 0 && upper.length == 0)
- {
- return "*";
- }
- if (lower.length == 1)
- {
- return "-" + ToSigForm(lower[0]);
- }
- if (upper.length == 1)
- {
- return "+" + ToSigForm(upper[0]);
- }
- // TODO
- throw new Error("Not Implemented");
- }
- else if(t instanceof java.lang.reflect.GenericArrayType)
- {
- java.lang.reflect.GenericArrayType a = (java.lang.reflect.GenericArrayType)t;
- return "[" + ToSigForm(a.getGenericComponentType());
- }
- else if(t instanceof Class)
- {
- return ClassToSig((Class)t);
- }
- else
- {
- throw new Error("Not Implemented: " + t);
- }
- }
-}
-
-class Modifiers
-{
- static final short Public = 0x0001;
- static final short Private = 0x0002;
- static final short Protected = 0x0004;
- static final short Static = 0x0008;
- static final short Final = 0x0010;
- static final short Super = 0x0020;
- static final short Synchronized = 0x0020;
- static final short Volatile = 0x0040;
- static final short Bridge = 0x0040;
- static final short Transient = 0x0080;
- static final short VarArgs = 0x0080;
- static final short Native = 0x0100;
- static final short Interface = 0x0200;
- static final short Abstract = 0x0400;
- static final short Strictfp = 0x0800;
- static final short Synthetic = 0x1000;
- static final short Annotation = 0x2000;
- static final short Enum = 0x4000;
-}
-
-class Constant
-{
- static final int Utf8 = 1;
- static final int Integer = 3;
- static final int Float = 4;
- static final int Long = 5;
- static final int Double = 6;
- static final int Class = 7;
- static final int String = 8;
- static final int Fieldref = 9;
- static final int Methodref = 10;
- static final int InterfaceMethodref = 11;
- static final int NameAndType = 12;
-}
-
-abstract class ConstantPoolItem
-{
- abstract void Write(DataOutputStream dos) throws IOException;
-}
-
-final class ConstantPoolItemClass extends ConstantPoolItem
-{
- private short name_index;
-
- public ConstantPoolItemClass(short name_index)
- {
- this.name_index = name_index;
- }
-
- public int hashCode()
- {
- return name_index;
- }
-
- public boolean equals(Object o)
- {
- if(o instanceof ConstantPoolItemClass)
- {
- return ((ConstantPoolItemClass)o).name_index == name_index;
- }
- return false;
- }
-
- void Write(DataOutputStream dos) throws IOException
- {
- dos.writeByte(Constant.Class);
- dos.writeShort(name_index);
- }
-}
-
-final class ConstantPoolItemMethodref extends ConstantPoolItem
-{
- private short class_index;
- private short name_and_type_index;
-
- public ConstantPoolItemMethodref(short class_index, short name_and_type_index)
- {
- this.class_index = class_index;
- this.name_and_type_index = name_and_type_index;
- }
-
- public int hashCode()
- {
- return (class_index & 0xFFFF) | (name_and_type_index << 16);
- }
-
- public boolean equals(Object o)
- {
- if(o instanceof ConstantPoolItemMethodref)
- {
- ConstantPoolItemMethodref m = (ConstantPoolItemMethodref)o;
- return m.class_index == class_index && m.name_and_type_index == name_and_type_index;
- }
- return false;
- }
-
- void Write(DataOutputStream dos) throws IOException
- {
- dos.writeByte(Constant.Methodref);
- dos.writeShort(class_index);
- dos.writeShort(name_and_type_index);
- }
-}
-
-final class ConstantPoolItemNameAndType extends ConstantPoolItem
-{
- private short name_index;
- private short descriptor_index;
-
- public ConstantPoolItemNameAndType(short name_index, short descriptor_index)
- {
- this.name_index = name_index;
- this.descriptor_index = descriptor_index;
- }
-
- public int hashCode()
- {
- return (name_index & 0xFFFF) | (descriptor_index << 16);
- }
-
- public boolean equals(Object o)
- {
- if(o instanceof ConstantPoolItemNameAndType)
- {
- ConstantPoolItemNameAndType n = (ConstantPoolItemNameAndType)o;
- return n.name_index == name_index && n.descriptor_index == descriptor_index;
- }
- return false;
- }
-
- void Write(DataOutputStream dos) throws IOException
- {
- dos.writeByte(Constant.NameAndType);
- dos.writeShort(name_index);
- dos.writeShort(descriptor_index);
- }
-}
-
-final class ConstantPoolItemUtf8 extends ConstantPoolItem
-{
- private String str;
-
- public ConstantPoolItemUtf8(String str)
- {
- this.str = str;
- }
-
- public int hashCode()
- {
- return str.hashCode();
- }
-
- public boolean equals(Object o)
- {
- if(o instanceof ConstantPoolItemUtf8)
- {
- return ((ConstantPoolItemUtf8)o).str.equals(str);
- }
- return false;
- }
-
- void Write(DataOutputStream dos) throws IOException
- {
- dos.writeByte(Constant.Utf8);
- dos.writeUTF(str);
- }
-}
-
-final class ConstantPoolItemInt extends ConstantPoolItem
-{
- private int v;
-
- public ConstantPoolItemInt(int v)
- {
- this.v = v;
- }
-
- public int hashCode()
- {
- return v;
- }
-
- public boolean equals(Object o)
- {
- if(o instanceof ConstantPoolItemInt)
- {
- return ((ConstantPoolItemInt)o).v == v;
- }
- return false;
- }
-
- void Write(DataOutputStream dos) throws IOException
- {
- dos.writeByte(Constant.Integer);
- dos.writeInt(v);
- }
-}
-
-final class ConstantPoolItemLong extends ConstantPoolItem
-{
- private long v;
-
- public ConstantPoolItemLong(long v)
- {
- this.v = v;
- }
-
- public int hashCode()
- {
- return (int)v;
- }
-
- public boolean equals(Object o)
- {
- if(o instanceof ConstantPoolItemLong)
- {
- return ((ConstantPoolItemLong)o).v == v;
- }
- return false;
- }
-
- void Write(DataOutputStream dos) throws IOException
- {
- dos.writeByte(Constant.Long);
- dos.writeLong(v);
- }
-}
-
-final class ConstantPoolItemFloat extends ConstantPoolItem
-{
- private float v;
-
- public ConstantPoolItemFloat(float v)
- {
- this.v = v;
- }
-
- public int hashCode()
- {
- return Float.floatToIntBits(v);
- }
-
- public boolean equals(Object o)
- {
- if(o instanceof ConstantPoolItemFloat)
- {
- return ((ConstantPoolItemFloat)o).v == v;
- }
- return false;
- }
-
- void Write(DataOutputStream dos) throws IOException
- {
- dos.writeByte(Constant.Float);
- dos.writeFloat(v);
- }
-}
-
-final class ConstantPoolItemDouble extends ConstantPoolItem
-{
- private double v;
-
- public ConstantPoolItemDouble(double v)
- {
- this.v = v;
- }
-
- public int hashCode()
- {
- long l = Double.doubleToLongBits(v);
- return ((int)l) ^ ((int)(l >> 32));
- }
-
- public boolean equals(Object o)
- {
- if(o instanceof ConstantPoolItemDouble)
- {
- return ((ConstantPoolItemDouble)o).v == v;
- }
- return false;
- }
-
- void Write(DataOutputStream dos) throws IOException
- {
- dos.writeByte(Constant.Double);
- dos.writeDouble(v);
- }
-}
-
-final class ConstantPoolItemString extends ConstantPoolItem
-{
- private short string_index;
-
- public ConstantPoolItemString(short string_index)
- {
- this.string_index = string_index;
- }
-
- public int hashCode()
- {
- return string_index;
- }
-
- public boolean equals(Object o)
- {
- if(o instanceof ConstantPoolItemString)
- {
- return ((ConstantPoolItemString)o).string_index == string_index;
- }
- return false;
- }
-
- void Write(DataOutputStream dos) throws IOException
- {
- dos.writeByte(Constant.String);
- dos.writeShort(string_index);
- }
-}
-
-class ClassFileAttribute
-{
- private short name_index;
-
- public ClassFileAttribute(short name_index)
- {
- this.name_index = name_index;
- }
-
- void Write(DataOutputStream dos) throws IOException
- {
- dos.writeShort(name_index);
- }
-}
-
-class DeprecatedAttribute extends ClassFileAttribute
-{
- DeprecatedAttribute(ClassFileWriter classFile)
- {
- super(classFile.AddUtf8("Deprecated"));
- }
-
- void Write(DataOutputStream dos) throws IOException
- {
- super.Write(dos);
- dos.writeInt(0);
- }
-}
-
-class ConstantValueAttribute extends ClassFileAttribute
-{
- private short constant_index;
-
- public ConstantValueAttribute(short name_index, short constant_index)
- {
- super(name_index);
- this.constant_index = constant_index;
- }
-
- void Write(DataOutputStream dos) throws IOException
- {
- super.Write(dos);
- dos.writeInt(2);
- dos.writeShort(constant_index);
- }
-}
-
-class StringAttribute extends ClassFileAttribute
-{
- private short string_index;
-
- public StringAttribute(short name_index, short string_index)
- {
- super(name_index);
- this.string_index = string_index;
- }
-
- void Write(DataOutputStream dos) throws IOException
- {
- super.Write(dos);
- dos.writeInt(2);
- dos.writeShort(string_index);
- }
-}
-
-class InnerClassesAttribute extends ClassFileAttribute
-{
- private ClassFileWriter classFile;
- private ArrayList classes = new ArrayList();
-
- public InnerClassesAttribute(ClassFileWriter classFile)
- {
- super(classFile.AddUtf8("InnerClasses"));
- this.classFile = classFile;
- }
-
- void Write(DataOutputStream dos) throws IOException
- {
- super.Write(dos);
- dos.writeInt(2 + 8 * classes.size());
- dos.writeShort(classes.size());
- for (int i = 0; i < classes.size(); i++)
- {
- Item it = (Item)classes.get(i);
- dos.writeShort(it.inner_class_info_index);
- dos.writeShort(it.outer_class_info_index);
- dos.writeShort(it.inner_name_index);
- dos.writeShort(it.inner_class_access_flags);
- }
- }
-
- private class Item
- {
- short inner_class_info_index;
- short outer_class_info_index;
- short inner_name_index;
- short inner_class_access_flags;
- }
-
- public void Add(String inner, String outer, String name, int access)
- {
- Item i = new Item();
- i.inner_class_info_index = classFile.AddClass(inner);
- i.outer_class_info_index = classFile.AddClass(outer);
- if(name != null)
- {
- i.inner_name_index = classFile.AddUtf8(name);
- }
- i.inner_class_access_flags = (short)access;
- classes.add(i);
- }
-}
-
-class ExceptionsAttribute extends ClassFileAttribute
-{
- private ClassFileWriter classFile;
- private ArrayList classes = new ArrayList();
-
- ExceptionsAttribute(ClassFileWriter classFile)
- {
- super(classFile.AddUtf8("Exceptions"));
- this.classFile = classFile;
- }
-
- void Add(String exceptionClass)
- {
- classes.add(classFile.AddClass(exceptionClass));
- }
-
- void Write(DataOutputStream dos) throws IOException
- {
- super.Write(dos);
- dos.writeInt(2 + 2 * classes.size());
- dos.writeShort(classes.size());
- for (int i = 0; i < classes.size(); i++)
- {
- short idx = (Short)classes.get(i);
- dos.writeShort(idx);
- }
- }
-}
-
-class RuntimeVisibleAnnotationsAttribute extends ClassFileAttribute
-{
- private ClassFileWriter classFile;
- private byte[] buf;
-
- RuntimeVisibleAnnotationsAttribute(ClassFileWriter classFile, Annotation[] annotations)
- {
- super(classFile.AddUtf8("RuntimeVisibleAnnotations"));
- this.classFile = classFile;
- try
- {
- ByteArrayOutputStream mem = new ByteArrayOutputStream();
- DataOutputStream dos = new DataOutputStream(mem);
- dos.writeShort((short)annotations.length);
- for(Annotation ann : annotations)
- {
- WriteAnnotation(classFile, dos, ann);
- }
- buf = mem.toByteArray();
- }
- catch(Exception x)
- {
- throw new Error(x);
- }
- }
-
- RuntimeVisibleAnnotationsAttribute(ClassFileWriter classFile, Annotation[][] parameterAnnotations)
- {
- super(classFile.AddUtf8("RuntimeVisibleParameterAnnotations"));
- this.classFile = classFile;
- try
- {
- ByteArrayOutputStream mem = new ByteArrayOutputStream();
- DataOutputStream dos = new DataOutputStream(mem);
- dos.writeByte(parameterAnnotations.length);
- for(Annotation[] annotations : parameterAnnotations)
- {
- dos.writeShort((short)annotations.length);
- for(Annotation ann : annotations)
- {
- WriteAnnotation(classFile, dos, ann);
- }
- }
- buf = mem.toByteArray();
- }
- catch(Exception x)
- {
- throw new Error(x);
- }
- }
-
- private static boolean deepEquals(Object o1, Object o2)
- {
- if (o1 == o2)
- return true;
-
- if (o1 == null || o2 == null)
- return false;
-
- if (o1 instanceof boolean[] && o2 instanceof boolean[])
- return Arrays.equals((boolean[]) o1, (boolean[]) o2);
-
- if (o1 instanceof byte[] && o2 instanceof byte[])
- return Arrays.equals((byte[]) o1, (byte[]) o2);
-
- if (o1 instanceof char[] && o2 instanceof char[])
- return Arrays.equals((char[]) o1, (char[]) o2);
-
- if (o1 instanceof short[] && o2 instanceof short[])
- return Arrays.equals((short[]) o1, (short[]) o2);
-
- if (o1 instanceof int[] && o2 instanceof int[])
- return Arrays.equals((int[]) o1, (int[]) o2);
-
- if (o1 instanceof float[] && o2 instanceof float[])
- return Arrays.equals((float[]) o1, (float[]) o2);
-
- if (o1 instanceof long[] && o2 instanceof long[])
- return Arrays.equals((long[]) o1, (long[]) o2);
-
- if (o1 instanceof double[] && o2 instanceof double[])
- return Arrays.equals((double[]) o1, (double[]) o2);
-
- if (o1 instanceof Object[] && o2 instanceof Object[])
- return Arrays.equals((Object[]) o1, (Object[]) o2);
-
- return o1.equals(o2);
- }
-
- static void WriteValue(ClassFileWriter classFile, DataOutputStream dos, Object val)
- throws IOException, IllegalAccessException, InvocationTargetException
- {
- if(val instanceof Boolean)
- {
- dos.writeByte('Z');
- dos.writeShort(classFile.AddInt(((Boolean)val).booleanValue() ? 1 : 0));
- }
- else if(val instanceof Byte)
- {
- dos.writeByte('B');
- dos.writeShort(classFile.AddInt(((Byte)val).byteValue()));
- }
- else if(val instanceof Character)
- {
- dos.writeByte('C');
- dos.writeShort(classFile.AddInt(((Character)val).charValue()));
- }
- else if(val instanceof Short)
- {
- dos.writeByte('S');
- dos.writeShort(classFile.AddInt(((Short)val).shortValue()));
- }
- else if(val instanceof Integer)
- {
- dos.writeByte('I');
- dos.writeShort(classFile.AddInt(((Integer)val).intValue()));
- }
- else if(val instanceof Float)
- {
- dos.writeByte('F');
- dos.writeShort(classFile.AddFloat(((Float)val).floatValue()));
- }
- else if(val instanceof Long)
- {
- dos.writeByte('J');
- dos.writeShort(classFile.AddLong(((Long)val).longValue()));
- }
- else if(val instanceof Double)
- {
- dos.writeByte('D');
- dos.writeShort(classFile.AddDouble(((Double)val).doubleValue()));
- }
- else if(val instanceof String)
- {
- dos.writeByte('s');
- dos.writeShort(classFile.AddUtf8((String)val));
- }
- else if(val instanceof Enum)
- {
- Enum enumVal = (Enum)val;
- Class enumType = enumVal.getDeclaringClass();
- dos.writeByte('e');
- dos.writeShort(classFile.AddUtf8("L" + enumType.getName().replace('.', '/') + ";"));
- dos.writeShort(classFile.AddUtf8(enumVal.name()));
- }
- else if(val instanceof Class)
- {
- dos.writeByte('c');
- Class c = (Class)val;
- String sig;
- if(c.isArray())
- {
- sig = c.getName();
- }
- else if(c == Boolean.TYPE)
- {
- sig = "Z";
- }
- else if(c == Byte.TYPE)
- {
- sig = "B";
- }
- else if(c == Character.TYPE)
- {
- sig = "C";
- }
- else if(c == Short.TYPE)
- {
- sig = "S";
- }
- else if(c == Integer.TYPE)
- {
- sig = "I";
- }
- else if(c == Float.TYPE)
- {
- sig = "F";
- }
- else if(c == Long.TYPE)
- {
- sig = "J";
- }
- else if(c == Double.TYPE)
- {
- sig = "D";
- }
- else if(c == Void.TYPE)
- {
- sig = "V";
- }
- else
- {
- sig = "L" + c.getName() + ";";
- }
- dos.writeShort(classFile.AddUtf8(sig.replace('.', '/')));
- }
- else if(val instanceof Annotation)
- {
- dos.writeByte('@');
- WriteAnnotation(classFile, dos, (Annotation)val);
- }
- else if(val.getClass().isArray())
- {
- dos.writeByte('[');
- int len = Array.getLength(val);
- dos.writeShort((short)len);
- for(int i = 0; i < len; i++)
- {
- WriteValue(classFile, dos, Array.get(val, i));
- }
- }
- else
- {
- throw new Error("Not Implemented: " + val.getClass());
- }
- }
-
- static void WriteAnnotation(ClassFileWriter classFile, DataOutputStream dos, Annotation ann)
- throws IOException, IllegalAccessException, InvocationTargetException
- {
- Class annotationType = ann.annotationType();
- dos.writeShort(classFile.AddUtf8("L" + annotationType.getName().replace('.', '/') + ";"));
- short numvalues = 0;
- Method[] methods = annotationType.getDeclaredMethods();
- for(int i = 0; i < methods.length; i++)
- {
- final Method m = methods[i];
- AccessController.doPrivileged(new PrivilegedAction() {
- public Object run() {
- m.setAccessible(true);
- return null;
- }
- });
- // HACK since there's no way to query if the annotation value is the default value
- // (and I don't want to add a private API for that), we simply compare the value
- // with the default and if they match we won't list the value.
- if(deepEquals(m.invoke(ann), m.getDefaultValue()))
- {
- methods[i] = null;
- }
- else
- {
- numvalues++;
- }
- }
- dos.writeShort(numvalues);
- for(Method m : methods)
- {
- if(m != null)
- {
- dos.writeShort(classFile.AddUtf8(m.getName()));
- WriteValue(classFile, dos, m.invoke(ann));
- }
- }
- }
-
- void Write(DataOutputStream dos) throws IOException
- {
- super.Write(dos);
- dos.writeInt(buf.length);
- dos.write(buf);
- }
-}
-
-class AnnotationDefaultClassFileAttribute extends ClassFileAttribute
-{
- private ClassFileWriter classFile;
- private byte[] buf;
-
- AnnotationDefaultClassFileAttribute(ClassFileWriter classFile, Object val)
- {
- super(classFile.AddUtf8("AnnotationDefault"));
- this.classFile = classFile;
- try
- {
- ByteArrayOutputStream mem = new ByteArrayOutputStream();
- DataOutputStream dos = new DataOutputStream(mem);
- RuntimeVisibleAnnotationsAttribute.WriteValue(classFile, dos, val);
- buf = mem.toByteArray();
- }
- catch (Exception x)
- {
- throw new Error(x);
- }
- }
-
- void Write(DataOutputStream dos) throws IOException
- {
- super.Write(dos);
- dos.writeInt(buf.length);
- dos.write(buf);
- }
-}
-
-class FieldOrMethod
-{
- private short access_flags;
- private short name_index;
- private short descriptor_index;
- private ArrayList attribs = new ArrayList();
-
- public FieldOrMethod(int access_flags, short name_index, short descriptor_index)
- {
- this.access_flags = (short)access_flags;
- this.name_index = name_index;
- this.descriptor_index = descriptor_index;
- }
-
- public void AddAttribute(ClassFileAttribute attrib)
- {
- attribs.add(attrib);
- }
-
- public void Write(DataOutputStream dos) throws IOException
- {
- dos.writeShort(access_flags);
- dos.writeShort(name_index);
- dos.writeShort(descriptor_index);
- dos.writeShort(attribs.size());
- for(int i = 0; i < attribs.size(); i++)
- {
- ((ClassFileAttribute)attribs.get(i)).Write(dos);
- }
- }
-}
-
-class CodeAttribute extends ClassFileAttribute
-{
- private ClassFileWriter classFile;
- private short max_stack;
- private short max_locals;
- private byte[] code;
-
- public CodeAttribute(ClassFileWriter classFile)
- {
- super(classFile.AddUtf8("Code"));
- this.classFile = classFile;
- }
-
- public void SetMaxStack(int v)
- {
- max_stack = (short)v;
- }
-
- public void SetMaxLocals(int v)
- {
- max_locals = (short)v;
- }
-
- public void SetByteCode(byte[] v)
- {
- code = v;
- }
-
- void Write(DataOutputStream dos) throws IOException
- {
- super.Write(dos);
- dos.writeInt(2 + 2 + 4 + code.length + 2 + 2);
- dos.writeShort(max_stack);
- dos.writeShort(max_locals);
- dos.writeInt(code.length);
- dos.write(code);
- dos.writeShort(0); // no exceptions
- dos.writeShort(0); // no attributes
- }
-}
-
-class ClassFileWriter
-{
- private ArrayList cplist = new ArrayList();
- private Hashtable cphashtable = new Hashtable();
- private ArrayList fields = new ArrayList();
- private ArrayList methods = new ArrayList();
- private ArrayList attribs = new ArrayList();
- private ArrayList interfaces = new ArrayList();
- private int access_flags;
- private short this_class;
- private short super_class;
- private short minorVersion;
- private short majorVersion;
-
- public ClassFileWriter(int mods, String name, String superClass, int minorVersion, int majorVersion)
- {
- cplist.add(null);
- access_flags = mods;
- this_class = AddClass(name);
- if(superClass != null)
- {
- super_class = AddClass(superClass);
- }
- this.minorVersion = (short)minorVersion;
- this.majorVersion = (short)majorVersion;
- }
-
- private short Add(ConstantPoolItem cpi)
- {
- Object index = cphashtable.get(cpi);
- if(index == null)
- {
- index = (short)cplist.size();
- cplist.add(cpi);
- if(cpi instanceof ConstantPoolItemDouble || cpi instanceof ConstantPoolItemLong)
- {
- cplist.add(null);
- }
- cphashtable.put(cpi, index);
- }
- return (Short)index;
- }
-
- public short AddUtf8(String str)
- {
- return Add(new ConstantPoolItemUtf8(str));
- }
-
- public short AddClass(String classname)
- {
- return Add(new ConstantPoolItemClass(AddUtf8(classname)));
- }
-
- public short AddMethodRef(String classname, String methodname, String signature)
- {
- return Add(new ConstantPoolItemMethodref(AddClass(classname), AddNameAndType(methodname, signature)));
- }
-
- public short AddNameAndType(String name, String type)
- {
- return Add(new ConstantPoolItemNameAndType(AddUtf8(name), AddUtf8(type)));
- }
-
- public short AddInt(int i)
- {
- return Add(new ConstantPoolItemInt(i));
- }
-
- public short AddLong(long l)
- {
- return Add(new ConstantPoolItemLong(l));
- }
-
- public short AddFloat(float f)
- {
- return Add(new ConstantPoolItemFloat(f));
- }
-
- public short AddDouble(double d)
- {
- return Add(new ConstantPoolItemDouble(d));
- }
-
- public short AddString(String s)
- {
- return Add(new ConstantPoolItemString(AddUtf8(s)));
- }
-
- public void AddInterface(String name)
- {
- interfaces.add(AddClass(name));
- }
-
- public FieldOrMethod AddMethod(int access, String name, String signature)
- {
- FieldOrMethod method = new FieldOrMethod(access, AddUtf8(name), AddUtf8(signature));
- methods.add(method);
- return method;
- }
-
- public FieldOrMethod AddField(int access, String name, String signature, Object constantValue)
- {
- FieldOrMethod field = new FieldOrMethod(access, AddUtf8(name), AddUtf8(signature));
- if(constantValue != null)
- {
- short constantValueIndex;
- if(constantValue instanceof Boolean)
- {
- constantValueIndex = AddInt(((Boolean)constantValue).booleanValue() ? 1 : 0);
- }
- else if(constantValue instanceof Byte)
- {
- constantValueIndex = AddInt(((Byte)constantValue).byteValue());
- }
- else if(constantValue instanceof Short)
- {
- constantValueIndex = AddInt(((Short)constantValue).shortValue());
- }
- else if(constantValue instanceof Character)
- {
- constantValueIndex = AddInt(((Character)constantValue).charValue());
- }
- else if(constantValue instanceof Integer)
- {
- constantValueIndex = AddInt(((Integer)constantValue).intValue());
- }
- else if(constantValue instanceof Long)
- {
- constantValueIndex = AddLong(((Long)constantValue).longValue());
- }
- else if(constantValue instanceof Float)
- {
- constantValueIndex = AddFloat(((Float)constantValue).floatValue());
- }
- else if(constantValue instanceof Double)
- {
- constantValueIndex = AddDouble(((Double)constantValue).doubleValue());
- }
- else if(constantValue instanceof String)
- {
- constantValueIndex = AddString((String)constantValue);
- }
- else
- {
- throw new Error();
- }
- field.AddAttribute(new ConstantValueAttribute(AddUtf8("ConstantValue"), constantValueIndex));
- }
- fields.add(field);
- return field;
- }
-
- public ClassFileAttribute MakeStringAttribute(String name, String value)
- {
- return new StringAttribute(AddUtf8(name), AddUtf8(value));
- }
-
- public void AddStringAttribute(String name, String value)
- {
- attribs.add(MakeStringAttribute(name, value));
- }
-
- public void AddAttribute(ClassFileAttribute attrib)
- {
- attribs.add(attrib);
- }
-
- public void Write(OutputStream stream) throws IOException
- {
- DataOutputStream dos = new DataOutputStream(stream);
- dos.writeInt(0xCAFEBABE);
- dos.writeShort(minorVersion);
- dos.writeShort(majorVersion);
- dos.writeShort(cplist.size());
- for(int i = 1; i < cplist.size(); i++)
- {
- ConstantPoolItem cpi = (ConstantPoolItem)cplist.get(i);
- if(cpi != null)
- {
- cpi.Write(dos);
- }
- }
- dos.writeShort(access_flags);
- dos.writeShort(this_class);
- dos.writeShort(super_class);
- // interfaces count
- dos.writeShort(interfaces.size());
- for(int i = 0; i < interfaces.size(); i++)
- {
- dos.writeShort((Short)interfaces.get(i));
- }
- // fields count
- dos.writeShort(fields.size());
- for(int i = 0; i < fields.size(); i++)
- {
- ((FieldOrMethod)fields.get(i)).Write(dos);
- }
- // methods count
- dos.writeShort(methods.size());
- for(int i = 0; i < methods.size(); i++)
- {
- ((FieldOrMethod)methods.get(i)).Write(dos);
- }
- // attributes count
- dos.writeShort(attribs.size());
- for(int i = 0; i < attribs.size(); i++)
- {
- ((ClassFileAttribute)attribs.get(i)).Write(dos);
- }
- }
-}
diff --git a/ikvmstub/ikvmstub.8.csproj b/ikvmstub/ikvmstub.8.csproj
index 822c2c2b..b1998f93 100644
--- a/ikvmstub/ikvmstub.8.csproj
+++ b/ikvmstub/ikvmstub.8.csproj
@@ -68,7 +68,7 @@
<Compile Include="AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
- <Compile Include="ClassFileWriter.cs" />
+ <Compile Include="..\runtime\stubgen\ClassFileWriter.cs" />
<Compile Include="ikvmstub.cs">
<SubType>Code</SubType>
</Compile>
@@ -102,7 +102,8 @@
<Compile Include="..\runtime\vm.cs">
<SubType>Code</SubType>
</Compile>
- <Compile Include="SerialVersionUID.cs" />
+ <Compile Include="..\runtime\stubgen\SerialVersionUID.cs" />
+ <Compile Include="..\runtime\stubgen\StubGenerator.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\reflect\IKVM.Reflection.csproj">
diff --git a/ikvmstub/ikvmstub.build b/ikvmstub/ikvmstub.build
index 02cd5342..8a829630 100644
--- a/ikvmstub/ikvmstub.build
+++ b/ikvmstub/ikvmstub.build
@@ -24,10 +24,11 @@
<include name="../runtime/Types.cs" />
<include name="../runtime/TypeWrapper.cs" />
<include name="../runtime/vm.cs" />
+ <include name="../runtime/stubgen/ClassFileWriter.cs" />
+ <include name="../runtime/stubgen/SerialVersionUID.cs" />
+ <include name="../runtime/stubgen/StubGenerator.cs" />
<include name="AssemblyInfo.cs" />
- <include name="ClassFileWriter.cs" />
<include name="ikvmstub.cs" />
- <include name="SerialVersionUID.cs" />
</sources>
<references>
<include name="../bin/ICSharpCode.SharpZipLib.dll" asis="true" />
diff --git a/ikvmstub/ikvmstub.cs b/ikvmstub/ikvmstub.cs
index e7f70d37..71446c9d 100644
--- a/ikvmstub/ikvmstub.cs
+++ b/ikvmstub/ikvmstub.cs
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2002-2012 Jeroen Frijters
+ Copyright (C) 2002-2013 Jeroen Frijters
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -321,469 +321,15 @@ static class NetExp
private static void WriteClass(TypeWrapper tw)
{
- string name = tw.Name.Replace('.', '/');
- string super = null;
- if (tw.IsInterface)
- {
- super = "java/lang/Object";
- }
- else if (tw.BaseTypeWrapper != null)
- {
- super = tw.BaseTypeWrapper.Name.Replace('.', '/');
- }
- IKVM.StubGen.ClassFileWriter writer = new IKVM.StubGen.ClassFileWriter(tw.Modifiers, name, super, 0, 49);
- foreach (TypeWrapper iface in tw.Interfaces)
- {
- if (iface.IsPublic || includeNonPublicInterfaces)
- {
- writer.AddInterface(iface.Name.Replace('.', '/'));
- }
- }
- IKVM.StubGen.InnerClassesAttribute innerClassesAttribute = null;
- if (tw.DeclaringTypeWrapper != null)
- {
- TypeWrapper outer = tw.DeclaringTypeWrapper;
- string innername = name;
- int idx = name.LastIndexOf('$');
- if (idx >= 0)
- {
- innername = innername.Substring(idx + 1);
- }
- innerClassesAttribute = new IKVM.StubGen.InnerClassesAttribute(writer);
- innerClassesAttribute.Add(name, outer.Name.Replace('.', '/'), innername, (ushort)tw.ReflectiveModifiers);
- }
- foreach (TypeWrapper inner in tw.InnerClasses)
- {
- if (inner.IsPublic)
- {
- if (innerClassesAttribute == null)
- {
- innerClassesAttribute = new IKVM.StubGen.InnerClassesAttribute(writer);
- }
- string namePart = inner.Name;
- namePart = namePart.Substring(namePart.LastIndexOf('$') + 1);
- innerClassesAttribute.Add(inner.Name.Replace('.', '/'), name, namePart, (ushort)inner.ReflectiveModifiers);
- }
- }
- if (innerClassesAttribute != null)
- {
- writer.AddAttribute(innerClassesAttribute);
- }
- string genericTypeSignature = tw.GetGenericSignature();
- if (genericTypeSignature != null)
- {
- writer.AddStringAttribute("Signature", genericTypeSignature);
- }
- writer.AddStringAttribute("IKVM.NET.Assembly", GetAssemblyName(tw));
- if (tw.TypeAsBaseType.IsDefined(StaticCompiler.Universe.Import(typeof(ObsoleteAttribute)), false))
- {
- writer.AddAttribute(new IKVM.StubGen.DeprecatedAttribute(writer));
- }
- foreach (MethodWrapper mw in tw.GetMethods())
- {
- if (!mw.IsHideFromReflection && (mw.IsPublic || mw.IsProtected || includeNonPublicMembers))
- {
- IKVM.StubGen.FieldOrMethod m;
- if (mw.Name == "<init>")
- {
- m = writer.AddMethod(mw.Modifiers, mw.Name, mw.Signature.Replace('.', '/'));
- IKVM.StubGen.CodeAttribute code = new IKVM.StubGen.CodeAttribute(writer);
- code.MaxLocals = (ushort)(mw.GetParameters().Length * 2 + 1);
- code.MaxStack = 3;
- ushort index1 = writer.AddClass("java/lang/UnsatisfiedLinkError");
- ushort index2 = writer.AddString("ikvmstub generated stubs can only be used on IKVM.NET");
- ushort index3 = writer.AddMethodRef("java/lang/UnsatisfiedLinkError", "<init>", "(Ljava/lang/String;)V");
- code.ByteCode = new byte[] {
- 187, (byte)(index1 >> 8), (byte)index1, // new java/lang/UnsatisfiedLinkError
- 89, // dup
- 19, (byte)(index2 >> 8), (byte)index2, // ldc_w "..."
- 183, (byte)(index3 >> 8), (byte)index3, // invokespecial java/lang/UnsatisfiedLinkError/init()V
- 191 // athrow
- };
- m.AddAttribute(code);
- }
- else
- {
- Modifiers mods = mw.Modifiers;
- if ((mods & Modifiers.Abstract) == 0)
- {
- mods |= Modifiers.Native;
- }
- m = writer.AddMethod(mods, mw.Name, mw.Signature.Replace('.', '/'));
- if (mw.IsOptionalAttributeAnnotationValue)
- {
- m.AddAttribute(new IKVM.StubGen.AnnotationDefaultClassFileAttribute(writer, GetAnnotationDefault(writer, mw.ReturnType)));
- }
- }
- MethodBase mb = mw.GetMethod();
- if (mb != null)
- {
- ThrowsAttribute throws = AttributeHelper.GetThrows(mb);
- if (throws == null)
- {
- string[] throwsArray = mw.GetDeclaredExceptions();
- if (throwsArray != null && throwsArray.Length > 0)
- {
- IKVM.StubGen.ExceptionsAttribute attrib = new IKVM.StubGen.ExceptionsAttribute(writer);
- foreach (string ex in throwsArray)
- {
- attrib.Add(ex.Replace('.', '/'));
- }
- m.AddAttribute(attrib);
- }
- }
- else
- {
- IKVM.StubGen.ExceptionsAttribute attrib = new IKVM.StubGen.ExceptionsAttribute(writer);
- if (throws.classes != null)
- {
- foreach (string ex in throws.classes)
- {
- attrib.Add(ex.Replace('.', '/'));
- }
- }
- if (throws.types != null)
- {
- foreach (Type ex in throws.types)
- {
- attrib.Add(ClassLoaderWrapper.GetWrapperFromType(ex).Name.Replace('.', '/'));
- }
- }
- m.AddAttribute(attrib);
- }
- if (mb.IsDefined(StaticCompiler.Universe.Import(typeof(ObsoleteAttribute)), false)
- // HACK the instancehelper methods are marked as Obsolete (to direct people toward the ikvm.extensions methods instead)
- // but in the Java world most of them are not deprecated (and to keep the Japi results clean we need to reflect this)
- && (!mb.Name.StartsWith("instancehelper_")
- || mb.DeclaringType.FullName != "java.lang.String"
- // the Java deprecated methods actually have two Obsolete attributes
- || mb.__GetCustomAttributes(StaticCompiler.Universe.Import(typeof(ObsoleteAttribute)), false).Count == 2))
- {
- m.AddAttribute(new IKVM.StubGen.DeprecatedAttribute(writer));
- }
- IList<CustomAttributeData> attr = CustomAttributeData.__GetCustomAttributes(mb, JVM.LoadType(typeof(AnnotationDefaultAttribute)), false);
- if (attr.Count == 1)
- {
- m.AddAttribute(new IKVM.StubGen.AnnotationDefaultClassFileAttribute(writer, GetAnnotationDefault(writer, attr[0].ConstructorArguments[0])));
- }
- }
- string sig = tw.GetGenericMethodSignature(mw);
- if (sig != null)
- {
- m.AddAttribute(writer.MakeStringAttribute("Signature", sig));
- }
- }
- }
- bool hasSerialVersionUID = false;
- foreach (FieldWrapper fw in tw.GetFields())
- {
- if (!fw.IsHideFromReflection)
- {
- bool isSerialVersionUID = includeSerialVersionUID && fw.Name == "serialVersionUID" && fw.FieldTypeWrapper == PrimitiveTypeWrapper.LONG;
- hasSerialVersionUID |= isSerialVersionUID;
- if (fw.IsPublic || fw.IsProtected || isSerialVersionUID || includeNonPublicMembers)
- {
- object constant = null;
- if (fw.GetField() != null && fw.GetField().IsLiteral && (fw.FieldTypeWrapper.IsPrimitive || fw.FieldTypeWrapper == CoreClasses.java.lang.String.Wrapper))
- {
- constant = fw.GetField().GetRawConstantValue();
- if (fw.GetField().FieldType.IsEnum)
- {
- constant = EnumHelper.GetPrimitiveValue(EnumHelper.GetUnderlyingType(fw.GetField().FieldType), constant);
- }
- }
- IKVM.StubGen.FieldOrMethod f = writer.AddField(fw.Modifiers, fw.Name, fw.Signature.Replace('.', '/'), constant);
- string sig = tw.GetGenericFieldSignature(fw);
- if (sig != null)
- {
- f.AddAttribute(writer.MakeStringAttribute("Signature", sig));
- }
- if (fw.GetField() != null && fw.GetField().IsDefined(StaticCompiler.Universe.Import(typeof(ObsoleteAttribute)), false))
- {
- f.AddAttribute(new IKVM.StubGen.DeprecatedAttribute(writer));
- }
- }
- }
- }
- if (includeSerialVersionUID && !hasSerialVersionUID && IsSerializable(tw))
- {
- // class is serializable but doesn't have an explicit serialVersionUID, so we add the field to record
- // the serialVersionUID as we see it (mainly to make the Japi reports more realistic)
- writer.AddField(Modifiers.Private | Modifiers.Static | Modifiers.Final, "serialVersionUID", "J", IKVM.StubGen.SerialVersionUID.Compute(tw));
- }
- AddMetaAnnotations(writer, tw);
zipCount++;
MemoryStream mem = new MemoryStream();
- writer.Write(mem);
- ZipEntry entry = new ZipEntry(name + ".class");
+ IKVM.StubGen.StubGenerator.WriteClass(mem, tw, includeNonPublicInterfaces, includeNonPublicMembers, includeSerialVersionUID);
+ ZipEntry entry = new ZipEntry(tw.Name.Replace('.', '/') + ".class");
entry.Size = mem.Position;
zipFile.PutNextEntry(entry);
mem.WriteTo(zipFile);
}
- private static string GetAssemblyName(TypeWrapper tw)
- {
- ClassLoaderWrapper loader = tw.GetClassLoader();
- AssemblyClassLoader acl = loader as AssemblyClassLoader;
- if (acl != null)
- {
- return acl.GetAssembly(tw).FullName;
- }
- else
- {
- return ((GenericClassLoaderWrapper)loader).GetName();
- }
- }
-
- private static bool IsSerializable(TypeWrapper tw)
- {
- if (tw.Name == "java.io.Serializable")
- {
- return true;
- }
- while (tw != null)
- {
- foreach (TypeWrapper iface in tw.Interfaces)
- {
- if (IsSerializable(iface))
- {
- return true;
- }
- }
- tw = tw.BaseTypeWrapper;
- }
- return false;
- }
-
- private static void AddMetaAnnotations(IKVM.StubGen.ClassFileWriter writer, TypeWrapper tw)
- {
- DotNetTypeWrapper.AttributeAnnotationTypeWrapperBase attributeAnnotation = tw as DotNetTypeWrapper.AttributeAnnotationTypeWrapperBase;
- if (attributeAnnotation != null)
- {
- // TODO write the annotation directly, instead of going thru the object[] encoding
- IKVM.StubGen.RuntimeVisibleAnnotationsAttribute annot = new IKVM.StubGen.RuntimeVisibleAnnotationsAttribute(writer);
- annot.Add(new object[] {
- AnnotationDefaultAttribute.TAG_ANNOTATION,
- "Ljava/lang/annotation/Retention;",
- "value",
- new object[] { AnnotationDefaultAttribute.TAG_ENUM, "Ljava/lang/annotation/RetentionPolicy;", "RUNTIME" }
- });
- AttributeTargets validOn = attributeAnnotation.AttributeTargets;
- List<object[]> targets = new List<object[]>();
- if ((validOn & (AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Delegate | AttributeTargets.Assembly)) != 0)
- {
- targets.Add(new object[] { AnnotationDefaultAttribute.TAG_ENUM, "Ljava/lang/annotation/ElementType;", "TYPE" });
- }
- if ((validOn & AttributeTargets.Constructor) != 0)
- {
- targets.Add(new object[] { AnnotationDefaultAttribute.TAG_ENUM, "Ljava/lang/annotation/ElementType;", "CONSTRUCTOR" });
- }
- if ((validOn & AttributeTargets.Field) != 0)
- {
- targets.Add(new object[] { AnnotationDefaultAttribute.TAG_ENUM, "Ljava/lang/annotation/ElementType;", "FIELD" });
- }
- if ((validOn & (AttributeTargets.Method | AttributeTargets.ReturnValue)) != 0)
- {
- targets.Add(new object[] { AnnotationDefaultAttribute.TAG_ENUM, "Ljava/lang/annotation/ElementType;", "METHOD" });
- }
- if ((validOn & AttributeTargets.Parameter) != 0)
- {
- targets.Add(new object[] { AnnotationDefaultAttribute.TAG_ENUM, "Ljava/lang/annotation/ElementType;", "PARAMETER" });
- }
- annot.Add(new object[] {
- AnnotationDefaultAttribute.TAG_ANNOTATION,
- "Ljava/lang/annotation/Target;",
- "value",
- new object[] { AnnotationDefaultAttribute.TAG_ARRAY, targets.ToArray() }
- });
- writer.AddAttribute(annot);
- }
- }
-
- private static byte[] GetAnnotationDefault(IKVM.StubGen.ClassFileWriter classFile, TypeWrapper type)
- {
- MemoryStream mem = new MemoryStream();
- IKVM.StubGen.BigEndianStream bes = new IKVM.StubGen.BigEndianStream(mem);
- if (type == PrimitiveTypeWrapper.BOOLEAN)
- {
- bes.WriteByte((byte)'Z');
- bes.WriteUInt16(classFile.AddInt(0));
- }
- else if(type == PrimitiveTypeWrapper.BYTE)
- {
- bes.WriteByte((byte)'B');
- bes.WriteUInt16(classFile.AddInt(0));
- }
- else if(type == PrimitiveTypeWrapper.CHAR)
- {
- bes.WriteByte((byte)'C');
- bes.WriteUInt16(classFile.AddInt(0));
- }
- else if(type == PrimitiveTypeWrapper.SHORT)
- {
- bes.WriteByte((byte)'S');
- bes.WriteUInt16(classFile.AddInt(0));
- }
- else if(type == PrimitiveTypeWrapper.INT)
- {
- bes.WriteByte((byte)'I');
- bes.WriteUInt16(classFile.AddInt(0));
- }
- else if(type == PrimitiveTypeWrapper.FLOAT)
- {
- bes.WriteByte((byte)'F');
- bes.WriteUInt16(classFile.AddFloat(0));
- }
- else if(type == PrimitiveTypeWrapper.LONG)
- {
- bes.WriteByte((byte)'J');
- bes.WriteUInt16(classFile.AddLong(0));
- }
- else if (type == PrimitiveTypeWrapper.DOUBLE)
- {
- bes.WriteByte((byte)'D');
- bes.WriteUInt16(classFile.AddDouble(0));
- }
- else if (type == CoreClasses.java.lang.String.Wrapper)
- {
- bes.WriteByte((byte)'s');
- bes.WriteUInt16(classFile.AddUtf8(""));
- }
- else if ((type.Modifiers & Modifiers.Enum) != 0)
- {
- bes.WriteByte((byte)'e');
- bes.WriteUInt16(classFile.AddUtf8("L" + type.Name.Replace('.', '/') + ";"));
- bes.WriteUInt16(classFile.AddUtf8("__unspecified"));
- }
- else if (type == CoreClasses.java.lang.Class.Wrapper)
- {
- bes.WriteByte((byte)'c');
- bes.WriteUInt16(classFile.AddUtf8("Likvm/internal/__unspecified;"));
- }
- else if (type.IsArray)
- {
- bes.WriteByte((byte)'[');
- bes.WriteUInt16(0);
- }
- else
- {
- throw new InvalidOperationException();
- }
- return mem.ToArray();
- }
-
- private static byte[] GetAnnotationDefault(IKVM.StubGen.ClassFileWriter classFile, CustomAttributeTypedArgument value)
- {
- MemoryStream mem = new MemoryStream();
- IKVM.StubGen.BigEndianStream bes = new IKVM.StubGen.BigEndianStream(mem);
- try
- {
- WriteAnnotationElementValue(classFile, bes, value);
- }
- catch (InvalidCastException)
- {
- Console.Error.WriteLine("Warning: incorrect annotation default value");
- }
- catch (IndexOutOfRangeException)
- {
- Console.Error.WriteLine("Warning: incorrect annotation default value");
- }
- return mem.ToArray();
- }
-
- private static void WriteAnnotationElementValue(IKVM.StubGen.ClassFileWriter classFile, IKVM.StubGen.BigEndianStream bes, CustomAttributeTypedArgument value)
- {
- if (value.ArgumentType == Types.Boolean)
- {
- bes.WriteByte((byte)'Z');
- bes.WriteUInt16(classFile.AddInt((bool)value.Value ? 1 : 0));
- }
- else if (value.ArgumentType == Types.Byte)
- {
- bes.WriteByte((byte)'B');
- bes.WriteUInt16(classFile.AddInt((byte)value.Value));
- }
- else if (value.ArgumentType == Types.Char)
- {
- bes.WriteByte((byte)'C');
- bes.WriteUInt16(classFile.AddInt((char)value.Value));
- }
- else if (value.ArgumentType == Types.Int16)
- {
- bes.WriteByte((byte)'S');
- bes.WriteUInt16(classFile.AddInt((short)value.Value));
- }
- else if (value.ArgumentType == Types.Int32)
- {
- bes.WriteByte((byte)'I');
- bes.WriteUInt16(classFile.AddInt((int)value.Value));
- }
- else if (value.ArgumentType == Types.Single)
- {
- bes.WriteByte((byte)'F');
- bes.WriteUInt16(classFile.AddFloat((float)value.Value));
- }
- else if (value.ArgumentType == Types.Int64)
- {
- bes.WriteByte((byte)'J');
- bes.WriteUInt16(classFile.AddLong((long)value.Value));
- }
- else if (value.ArgumentType == Types.Double)
- {
- bes.WriteByte((byte)'D');
- bes.WriteUInt16(classFile.AddDouble((double)value.Value));
- }
- else if (value.ArgumentType == Types.String)
- {
- bes.WriteByte((byte)'s');
- bes.WriteUInt16(classFile.AddUtf8((string)value.Value));
- }
- else if (value.ArgumentType == Types.Object.MakeArrayType())
- {
- CustomAttributeTypedArgument[] array = (CustomAttributeTypedArgument[])value.Value;
- byte type = (byte)array[0].Value;
- if (type == AnnotationDefaultAttribute.TAG_ARRAY)
- {
- bes.WriteByte((byte)'[');
- bes.WriteUInt16((ushort)(array.Length - 1));
- for (int i = 1; i < array.Length; i++)
- {
- WriteAnnotationElementValue(classFile, bes, array[i]);
- }
- }
- else if (type == AnnotationDefaultAttribute.TAG_CLASS)
- {
- bes.WriteByte((byte)'c');
- bes.WriteUInt16(classFile.AddUtf8((string)array[1].Value));
- }
- else if (type == AnnotationDefaultAttribute.TAG_ENUM)
- {
- bes.WriteByte((byte)'e');
- bes.WriteUInt16(classFile.AddUtf8((string)array[1].Value));
- bes.WriteUInt16(classFile.AddUtf8((string)array[2].Value));
- }
- else if (type == AnnotationDefaultAttribute.TAG_ANNOTATION)
- {
- bes.WriteByte((byte)'@');
- bes.WriteUInt16(classFile.AddUtf8((string)array[1].Value));
- bes.WriteUInt16((ushort)((array.Length - 2) / 2));
- for (int i = 2; i < array.Length; i += 2)
- {
- bes.WriteUInt16(classFile.AddUtf8((string)array[i].Value));
- WriteAnnotationElementValue(classFile, bes, array[i + 1]);
- }
- }
- else
- {
- Console.Error.WriteLine("Warning: incorrect annotation default element tag: " + type);
- }
- }
- else
- {
- Console.Error.WriteLine("Warning: incorrect annotation default element type: " + value.ArgumentType);
- }
- }
-
private static bool ExportNamespace(Type type)
{
if (namespaces.Count == 0)
diff --git a/openjdk/allsources.lst b/openjdk/allsources.lst
index b3b62f30..5df16cb5 100644
--- a/openjdk/allsources.lst
+++ b/openjdk/allsources.lst
@@ -7,7 +7,6 @@
../classpath/ikvm/internal/HasCallerID.java
../classpath/ikvm/internal/JMath.java
../classpath/ikvm/internal/MonoUtils.java
-../classpath/ikvm/internal/stubgen/StubGenerator.java
../classpath/ikvm/internal/Util.java
../classpath/ikvm/internal/WeakIdentityMap.java
../classpath/ikvm/io/InputStreamWrapper.java
diff --git a/openjdk/response.txt b/openjdk/response.txt
index 0aa4d190..9dca1438 100644
--- a/openjdk/response.txt
+++ b/openjdk/response.txt
@@ -55,7 +55,6 @@ assembly.class
../classpath/gnu/java/net/protocol/ikvmres/*.class
../classpath/ikvm/extensions/*.class
../classpath/ikvm/internal/*.class
- ../classpath/ikvm/internal/stubgen/*.class
../classpath/ikvm/io/*.class
../classpath/ikvm/lang/*.class
../classpath/ikvm/runtime/*.class
@@ -168,7 +167,7 @@ assembly.class
}
{
-out:IKVM.OpenJDK.Corba.dll
- -baseaddress:0x56C90000
+ -baseaddress:0x56C60000
-recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/corba/*
-recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/jndi/cosnaming/jndiprovider.properties
@OPENJDK7@/build/linux-amd64/impsrc/com/sun/corba/se/impl/activation/*.class
@@ -286,7 +285,7 @@ assembly.class
}
{
-out:IKVM.OpenJDK.XML.API.dll
- -baseaddress:0x572F0000
+ -baseaddress:0x572C0000
@OPENJDK7@/build/linux-amd64/impsrc/javax/xml/*.class
@OPENJDK7@/build/linux-amd64/impsrc/javax/xml/datatype/*.class
@OPENJDK7@/build/linux-amd64/impsrc/javax/xml/namespace/*.class
@@ -319,7 +318,7 @@ assembly.class
}
{
-out:IKVM.OpenJDK.XML.XPath.dll
- -baseaddress:0x573B0000
+ -baseaddress:0x57380000
-recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/org/apache/xalan/internal/res/*
@OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xalan/internal/extensions/*.class
@OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xalan/internal/res/*.class
@@ -344,7 +343,7 @@ assembly.class
}
{
-out:IKVM.OpenJDK.XML.Parse.dll
- -baseaddress:0x57710000
+ -baseaddress:0x576E0000
-resource:com/sun/org/apache/xml/internal/serialize/HTMLEntities.res=@OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/xml/internal/serialize/HTMLEntities.res
-recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/org/apache/xerces/*
-recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/org/apache/xml/internal/serializer/*
@@ -405,7 +404,7 @@ assembly.class
}
{
-out:IKVM.OpenJDK.XML.Transform.dll
- -baseaddress:0x57EC0000
+ -baseaddress:0x57E90000
@OPENJDK7@/build/linux-amd64/impsrc/com/sun/java_cup/internal/runtime/*.class
@OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/bcel/internal/*.class
@OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/apache/bcel/internal/classfile/*.class
@@ -429,7 +428,7 @@ assembly.class
}
{
-out:IKVM.OpenJDK.XML.Bind.dll
- -baseaddress:0x58310000
+ -baseaddress:0x582E0000
-recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/javax/xml/bind/*
-recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/xml/internal/bind/*
-recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/xml/internal/fastinfoset/*
@@ -488,7 +487,7 @@ assembly.class
}
{
-out:IKVM.OpenJDK.XML.WebServices.dll
- -baseaddress:0x586A0000
+ -baseaddress:0x58670000
-recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/xml/internal/messaging/*
-recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/xml/internal/ws/*
@OPENJDK7@/build/linux-amd64/impsrc/com/sun/org/glassfish/external/amx/*.class
@@ -608,7 +607,7 @@ assembly.class
}
{
-out:IKVM.OpenJDK.XML.Crypto.dll
- -baseaddress:0x58C10000
+ -baseaddress:0x58BE0000
-recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/org/apache/xml/internal/security/*
@OPENJDK7@/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/*.class
@OPENJDK7@/jdk/src/share/classes/com/sun/org/apache/xml/internal/security/algorithms/*.class
@@ -644,7 +643,7 @@ assembly.class
}
{
-out:IKVM.OpenJDK.SwingAWT.dll
- -baseaddress:0x58D60000
+ -baseaddress:0x58D30000
-remap:swingawt.xml
-resource:META-INF/services/sun.java2d.pipe.RenderingEngine=resources/META-INF/services/sun.java2d.pipe.RenderingEngine
-recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/META-INF/services/sun.java2d.cmm.PCMM
@@ -744,7 +743,7 @@ assembly.class
}
{
-out:IKVM.OpenJDK.Charsets.dll
- -baseaddress:0x59F60000
+ -baseaddress:0x59F30000
-recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/charsets.jar/sun/nio/cs/ext/sjis0213.dat
-recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/charsets.jar/META-INF/services/java.nio.charset.spi.CharsetProvider
@OPENJDK7@/build/linux-amd64/gensrc/sun/nio/cs/ext/*.class
@@ -753,7 +752,7 @@ assembly.class
}
{
-out:IKVM.OpenJDK.Util.dll
- -baseaddress:0x5A5F0000
+ -baseaddress:0x5A5C0000
-recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/java/util/jar/pack/intrinsic.properties
-recurse:resources.zip/sun/launcher/resources/*
-resource:META-INF/services/java.nio.file.spi.FileSystemProvider=@OPENJDK7@/jdk/src/share/demo/nio/zipfs/src/META-INF/services/java.nio.file.spi.FileSystemProvider
@@ -776,7 +775,7 @@ assembly.class
}
{
-out:IKVM.OpenJDK.Text.dll
- -baseaddress:0x5ABC0000
+ -baseaddress:0x5AB90000
-recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/sun/text/*
@OPENJDK7@/build/linux-amd64/j2re-image/lib/ext/localedata.jar
@OPENJDK7@/jdk/src/share/classes/java/text/*.class
@@ -788,7 +787,7 @@ assembly.class
}
{
-out:IKVM.OpenJDK.Security.dll
- -baseaddress:0x5AE30000
+ -baseaddress:0x5AE00000
-remap:security.xml
sun/security/jgss/wrapper/*.class
@OPENJDK7@/jdk/src/share/classes/com/sun/crypto/provider/*.class
@@ -859,7 +858,7 @@ assembly.class
}
{
-out:IKVM.OpenJDK.Management.dll
- -baseaddress:0x5B640000
+ -baseaddress:0x5B610000
com/sun/management/*.class
java/lang/management/*.class
sun/management/*.class
@@ -893,7 +892,7 @@ assembly.class
}
{
-out:IKVM.OpenJDK.Misc.dll
- -baseaddress:0x5B9A0000
+ -baseaddress:0x5B970000
-resource:com/sun/servicetag/resources/javase_5_swordfish.properties=@OPENJDK7@/jdk/src/share/classes/com/sun/servicetag/resources/javase_5_swordfish.properties
-resource:com/sun/servicetag/resources/javase_6_swordfish.properties=@OPENJDK7@/jdk/src/share/classes/com/sun/servicetag/resources/javase_6_swordfish.properties
-resource:com/sun/servicetag/resources/javase_7_swordfish.properties=@OPENJDK7@/jdk/src/share/classes/com/sun/servicetag/resources/javase_7_swordfish.properties
@@ -994,7 +993,7 @@ assembly.class
}
{
-out:IKVM.OpenJDK.Naming.dll
- -baseaddress:0x5BAC0000
+ -baseaddress:0x5BA90000
-recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/jndi/ldap/jndiprovider.properties
-resource:META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor=@OPENJDK7@/jdk/src/share/classes/sun/net/spi/nameservice/dns/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor
sun/net/dns/*.class
@@ -1020,7 +1019,7 @@ assembly.class
}
{
-out:IKVM.OpenJDK.Jdbc.dll
- -baseaddress:0x5BC10000
+ -baseaddress:0x5BBE0000
-resource:META-INF/services/java.sql.Driver=resources/META-INF/services/java.sql.Driver
-recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/rowset/*
-recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/javax/sql/*
@@ -1038,7 +1037,7 @@ assembly.class
}
{
-out:IKVM.OpenJDK.Remoting.dll
- -baseaddress:0x5BD60000
+ -baseaddress:0x5BD30000
-recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/sun/rmi/*
@OPENJDK7@/build/linux-amd64/classes/sun/rmi/registry/*.class
@OPENJDK7@/build/linux-amd64/classes/sun/rmi/server/*.class
@@ -1064,7 +1063,7 @@ assembly.class
}
{
-out:IKVM.OpenJDK.Beans.dll
- -baseaddress:0x5BE80000
+ -baseaddress:0x5BE50000
@OPENJDK7@/build/linux-amd64/impsrc/com/sun/activation/registries/*.class
@OPENJDK7@/build/linux-amd64/impsrc/javax/activation/*.class
@OPENJDK7@/jdk/src/share/classes/com/sun/beans/*.class
@@ -1077,7 +1076,7 @@ assembly.class
}
{
-out:IKVM.OpenJDK.Media.dll
- -baseaddress:0x5BF40000
+ -baseaddress:0x5BF10000
-recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/META-INF/services/javax.print.*
-recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/META-INF/services/javax.sound.*
-recurse:@OPENJDK7@/build/linux-amd64/j2re-image/lib/resources.jar/com/sun/imageio/plugins/common/iio-plugin.properties
diff --git a/runtime/IKVM.Runtime.8.csproj b/runtime/IKVM.Runtime.8.csproj
index 5709b830..15f4814c 100644
--- a/runtime/IKVM.Runtime.8.csproj
+++ b/runtime/IKVM.Runtime.8.csproj
@@ -157,6 +157,9 @@
<Compile Include="ReflectUtil.cs" />
<Compile Include="RuntimeHelperTypes.cs" />
<Compile Include="Serialization.cs" />
+ <Compile Include="stubgen\ClassFileWriter.cs" />
+ <Compile Include="stubgen\SerialVersionUID.cs" />
+ <Compile Include="stubgen\StubGenerator.cs" />
<Compile Include="tracer.cs">
<SubType>Code</SubType>
</Compile>
diff --git a/runtime/common.cs b/runtime/common.cs
index 3076ad90..19dfc7ae 100644
--- a/runtime/common.cs
+++ b/runtime/common.cs
@@ -44,6 +44,16 @@ namespace IKVM.NativeCode.gnu.java.net.protocol.ikvmres
{
static class Handler
{
+ public static byte[] GenerateStub(jlClass c)
+ {
+ MemoryStream mem = new MemoryStream();
+#if !FIRST_PASS
+ bool includeNonPublicInterfaces = !"true".Equals(global::java.lang.Props.props.getProperty("ikvm.stubgen.skipNonPublicInterfaces"), StringComparison.OrdinalIgnoreCase);
+ IKVM.StubGen.StubGenerator.WriteClass(mem, TypeWrapper.FromClass(c), includeNonPublicInterfaces, false, false);
+#endif
+ return mem.ToArray();
+ }
+
public static Stream ReadResourceFromAssemblyImpl(Assembly asm, string resource)
{
// chop off the leading slash
diff --git a/runtime/openjdk.cs b/runtime/openjdk.cs
index d3cc9d34..c1fe52d4 100644
--- a/runtime/openjdk.cs
+++ b/runtime/openjdk.cs
@@ -89,7 +89,6 @@ using srFieldAccessor = sun.reflect.FieldAccessor;
using srLangReflectAccess = sun.reflect.LangReflectAccess;
using srReflection = sun.reflect.Reflection;
using srReflectionFactory = sun.reflect.ReflectionFactory;
-using StubGenerator = ikvm.@internal.stubgen.StubGenerator;
using Annotation = java.lang.annotation.Annotation;
using smJavaIOAccess = sun.misc.JavaIOAccess;
using smLauncher = sun.misc.Launcher;
diff --git a/runtime/runtime.build b/runtime/runtime.build
index ab53b85b..96e1bb2a 100644
--- a/runtime/runtime.build
+++ b/runtime/runtime.build
@@ -155,6 +155,9 @@
<include name="openjdk/sun.management.cs" />
<include name="openjdk/sun.nio.ch.cs" />
<include name="openjdk/sun.security.krb5.cs" />
+ <include name="stubgen/ClassFileWriter.cs" />
+ <include name="stubgen/SerialVersionUID.cs" />
+ <include name="stubgen/StubGenerator.cs" />
</sources>
<resources>
<include if="${not first-pass}" name="../openjdk/vfs.zip" />
diff --git a/ikvmstub/ClassFileWriter.cs b/runtime/stubgen/ClassFileWriter.cs
index 197746ac..197746ac 100644
--- a/ikvmstub/ClassFileWriter.cs
+++ b/runtime/stubgen/ClassFileWriter.cs
diff --git a/ikvmstub/SerialVersionUID.cs b/runtime/stubgen/SerialVersionUID.cs
index 255a0ff8..fc972d28 100644
--- a/ikvmstub/SerialVersionUID.cs
+++ b/runtime/stubgen/SerialVersionUID.cs
@@ -27,7 +27,9 @@ using System.IO;
using System.Text;
using IKVM.Attributes;
using IKVM.Internal;
+#if STUB_GENERATOR
using Type = IKVM.Reflection.Type;
+#endif
namespace IKVM.StubGen
{
diff --git a/runtime/stubgen/StubGenerator.cs b/runtime/stubgen/StubGenerator.cs
new file mode 100644
index 00000000..99378d7f
--- /dev/null
+++ b/runtime/stubgen/StubGenerator.cs
@@ -0,0 +1,525 @@
+/*
+ Copyright (C) 2002-2013 Jeroen Frijters
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jeroen Frijters
+ jeroen@frijters.net
+
+*/
+using System;
+using System.IO;
+using System.Collections.Generic;
+#if STUB_GENERATOR
+using IKVM.Reflection;
+using Type = IKVM.Reflection.Type;
+#else
+using System.Reflection;
+#endif
+using IKVM.Attributes;
+using IKVM.Internal;
+
+namespace IKVM.StubGen
+{
+ static class StubGenerator
+ {
+ internal static void WriteClass(Stream stream, TypeWrapper tw, bool includeNonPublicInterfaces, bool includeNonPublicMembers, bool includeSerialVersionUID)
+ {
+ string name = tw.Name.Replace('.', '/');
+ string super = null;
+ if (tw.IsInterface)
+ {
+ super = "java/lang/Object";
+ }
+ else if (tw.BaseTypeWrapper != null)
+ {
+ super = tw.BaseTypeWrapper.Name.Replace('.', '/');
+ }
+ IKVM.StubGen.ClassFileWriter writer = new IKVM.StubGen.ClassFileWriter(tw.Modifiers, name, super, 0, 49);
+ foreach (TypeWrapper iface in tw.Interfaces)
+ {
+ if (iface.IsPublic || includeNonPublicInterfaces)
+ {
+ writer.AddInterface(iface.Name.Replace('.', '/'));
+ }
+ }
+ IKVM.StubGen.InnerClassesAttribute innerClassesAttribute = null;
+ if (tw.DeclaringTypeWrapper != null)
+ {
+ TypeWrapper outer = tw.DeclaringTypeWrapper;
+ string innername = name;
+ int idx = name.LastIndexOf('$');
+ if (idx >= 0)
+ {
+ innername = innername.Substring(idx + 1);
+ }
+ innerClassesAttribute = new IKVM.StubGen.InnerClassesAttribute(writer);
+ innerClassesAttribute.Add(name, outer.Name.Replace('.', '/'), innername, (ushort)tw.ReflectiveModifiers);
+ }
+ foreach (TypeWrapper inner in tw.InnerClasses)
+ {
+ if (inner.IsPublic)
+ {
+ if (innerClassesAttribute == null)
+ {
+ innerClassesAttribute = new IKVM.StubGen.InnerClassesAttribute(writer);
+ }
+ string namePart = inner.Name;
+ namePart = namePart.Substring(namePart.LastIndexOf('$') + 1);
+ innerClassesAttribute.Add(inner.Name.Replace('.', '/'), name, namePart, (ushort)inner.ReflectiveModifiers);
+ }
+ }
+ if (innerClassesAttribute != null)
+ {
+ writer.AddAttribute(innerClassesAttribute);
+ }
+ string genericTypeSignature = tw.GetGenericSignature();
+ if (genericTypeSignature != null)
+ {
+ writer.AddStringAttribute("Signature", genericTypeSignature);
+ }
+ writer.AddStringAttribute("IKVM.NET.Assembly", GetAssemblyName(tw));
+ if (tw.TypeAsBaseType.IsDefined(JVM.Import(typeof(ObsoleteAttribute)), false))
+ {
+ writer.AddAttribute(new IKVM.StubGen.DeprecatedAttribute(writer));
+ }
+ foreach (MethodWrapper mw in tw.GetMethods())
+ {
+ if (!mw.IsHideFromReflection && (mw.IsPublic || mw.IsProtected || includeNonPublicMembers))
+ {
+ IKVM.StubGen.FieldOrMethod m;
+ if (mw.Name == "<init>")
+ {
+ m = writer.AddMethod(mw.Modifiers, mw.Name, mw.Signature.Replace('.', '/'));
+ IKVM.StubGen.CodeAttribute code = new IKVM.StubGen.CodeAttribute(writer);
+ code.MaxLocals = (ushort)(mw.GetParameters().Length * 2 + 1);
+ code.MaxStack = 3;
+ ushort index1 = writer.AddClass("java/lang/UnsatisfiedLinkError");
+ ushort index2 = writer.AddString("ikvmstub generated stubs can only be used on IKVM.NET");
+ ushort index3 = writer.AddMethodRef("java/lang/UnsatisfiedLinkError", "<init>", "(Ljava/lang/String;)V");
+ code.ByteCode = new byte[] {
+ 187, (byte)(index1 >> 8), (byte)index1, // new java/lang/UnsatisfiedLinkError
+ 89, // dup
+ 19, (byte)(index2 >> 8), (byte)index2, // ldc_w "..."
+ 183, (byte)(index3 >> 8), (byte)index3, // invokespecial java/lang/UnsatisfiedLinkError/init()V
+ 191 // athrow
+ };
+ m.AddAttribute(code);
+ }
+ else
+ {
+ Modifiers mods = mw.Modifiers;
+ if ((mods & Modifiers.Abstract) == 0)
+ {
+ mods |= Modifiers.Native;
+ }
+ m = writer.AddMethod(mods, mw.Name, mw.Signature.Replace('.', '/'));
+ if (mw.IsOptionalAttributeAnnotationValue)
+ {
+ m.AddAttribute(new IKVM.StubGen.AnnotationDefaultClassFileAttribute(writer, GetAnnotationDefault(writer, mw.ReturnType)));
+ }
+ }
+ MethodBase mb = mw.GetMethod();
+ if (mb != null)
+ {
+ ThrowsAttribute throws = AttributeHelper.GetThrows(mb);
+ if (throws == null)
+ {
+ string[] throwsArray = mw.GetDeclaredExceptions();
+ if (throwsArray != null && throwsArray.Length > 0)
+ {
+ IKVM.StubGen.ExceptionsAttribute attrib = new IKVM.StubGen.ExceptionsAttribute(writer);
+ foreach (string ex in throwsArray)
+ {
+ attrib.Add(ex.Replace('.', '/'));
+ }
+ m.AddAttribute(attrib);
+ }
+ }
+ else
+ {
+ IKVM.StubGen.ExceptionsAttribute attrib = new IKVM.StubGen.ExceptionsAttribute(writer);
+ if (throws.classes != null)
+ {
+ foreach (string ex in throws.classes)
+ {
+ attrib.Add(ex.Replace('.', '/'));
+ }
+ }
+ if (throws.types != null)
+ {
+ foreach (Type ex in throws.types)
+ {
+ attrib.Add(ClassLoaderWrapper.GetWrapperFromType(ex).Name.Replace('.', '/'));
+ }
+ }
+ m.AddAttribute(attrib);
+ }
+ if (mb.IsDefined(JVM.Import(typeof(ObsoleteAttribute)), false)
+ // HACK the instancehelper methods are marked as Obsolete (to direct people toward the ikvm.extensions methods instead)
+ // but in the Java world most of them are not deprecated (and to keep the Japi results clean we need to reflect this)
+ && (!mb.Name.StartsWith("instancehelper_")
+ || mb.DeclaringType.FullName != "java.lang.String"
+ // the Java deprecated methods actually have two Obsolete attributes
+ || GetObsoleteCount(mb) == 2))
+ {
+ m.AddAttribute(new IKVM.StubGen.DeprecatedAttribute(writer));
+ }
+ CustomAttributeData attr = GetAnnotationDefault(mb);
+ if (attr != null)
+ {
+ m.AddAttribute(new IKVM.StubGen.AnnotationDefaultClassFileAttribute(writer, GetAnnotationDefault(writer, attr.ConstructorArguments[0])));
+ }
+ }
+ string sig = tw.GetGenericMethodSignature(mw);
+ if (sig != null)
+ {
+ m.AddAttribute(writer.MakeStringAttribute("Signature", sig));
+ }
+ }
+ }
+ bool hasSerialVersionUID = false;
+ foreach (FieldWrapper fw in tw.GetFields())
+ {
+ if (!fw.IsHideFromReflection)
+ {
+ bool isSerialVersionUID = includeSerialVersionUID && fw.Name == "serialVersionUID" && fw.FieldTypeWrapper == PrimitiveTypeWrapper.LONG;
+ hasSerialVersionUID |= isSerialVersionUID;
+ if (fw.IsPublic || fw.IsProtected || isSerialVersionUID || includeNonPublicMembers)
+ {
+ object constant = null;
+ if (fw.GetField() != null && fw.GetField().IsLiteral && (fw.FieldTypeWrapper.IsPrimitive || fw.FieldTypeWrapper == CoreClasses.java.lang.String.Wrapper))
+ {
+ constant = fw.GetField().GetRawConstantValue();
+ if (fw.GetField().FieldType.IsEnum)
+ {
+ constant = EnumHelper.GetPrimitiveValue(EnumHelper.GetUnderlyingType(fw.GetField().FieldType), constant);
+ }
+ }
+ IKVM.StubGen.FieldOrMethod f = writer.AddField(fw.Modifiers, fw.Name, fw.Signature.Replace('.', '/'), constant);
+ string sig = tw.GetGenericFieldSignature(fw);
+ if (sig != null)
+ {
+ f.AddAttribute(writer.MakeStringAttribute("Signature", sig));
+ }
+ if (fw.GetField() != null && fw.GetField().IsDefined(JVM.Import(typeof(ObsoleteAttribute)), false))
+ {
+ f.AddAttribute(new IKVM.StubGen.DeprecatedAttribute(writer));
+ }
+ }
+ }
+ }
+ if (includeSerialVersionUID && !hasSerialVersionUID && IsSerializable(tw))
+ {
+ // class is serializable but doesn't have an explicit serialVersionUID, so we add the field to record
+ // the serialVersionUID as we see it (mainly to make the Japi reports more realistic)
+ writer.AddField(Modifiers.Private | Modifiers.Static | Modifiers.Final, "serialVersionUID", "J", IKVM.StubGen.SerialVersionUID.Compute(tw));
+ }
+ AddMetaAnnotations(writer, tw);
+ writer.Write(stream);
+ }
+
+ private static int GetObsoleteCount(MethodBase mb)
+ {
+#if STUB_GENERATOR
+ return mb.__GetCustomAttributes(JVM.Import(typeof(ObsoleteAttribute)), false).Count;
+#else
+ return mb.GetCustomAttributes(typeof(ObsoleteAttribute), false).Length;
+#endif
+ }
+
+ private static CustomAttributeData GetAnnotationDefault(MethodBase mb)
+ {
+#if STUB_GENERATOR
+ IList<CustomAttributeData> attr = CustomAttributeData.__GetCustomAttributes(mb, JVM.LoadType(typeof(AnnotationDefaultAttribute)), false);
+ return attr.Count == 1 ? attr[0] : null;
+#else
+ foreach (CustomAttributeData cad in CustomAttributeData.GetCustomAttributes(mb))
+ {
+ if (cad.Constructor.DeclaringType == typeof(AnnotationDefaultAttribute))
+ {
+ return cad;
+ }
+ }
+ return null;
+#endif
+ }
+
+ private static string GetAssemblyName(TypeWrapper tw)
+ {
+ ClassLoaderWrapper loader = tw.GetClassLoader();
+ AssemblyClassLoader acl = loader as AssemblyClassLoader;
+ if (acl != null)
+ {
+ return acl.GetAssembly(tw).FullName;
+ }
+ else
+ {
+ return ((GenericClassLoaderWrapper)loader).GetName();
+ }
+ }
+
+ private static bool IsSerializable(TypeWrapper tw)
+ {
+ if (tw.Name == "java.io.Serializable")
+ {
+ return true;
+ }
+ while (tw != null)
+ {
+ foreach (TypeWrapper iface in tw.Interfaces)
+ {
+ if (IsSerializable(iface))
+ {
+ return true;
+ }
+ }
+ tw = tw.BaseTypeWrapper;
+ }
+ return false;
+ }
+
+ private static void AddMetaAnnotations(IKVM.StubGen.ClassFileWriter writer, TypeWrapper tw)
+ {
+ DotNetTypeWrapper.AttributeAnnotationTypeWrapperBase attributeAnnotation = tw as DotNetTypeWrapper.AttributeAnnotationTypeWrapperBase;
+ if (attributeAnnotation != null)
+ {
+ // TODO write the annotation directly, instead of going thru the object[] encoding
+ IKVM.StubGen.RuntimeVisibleAnnotationsAttribute annot = new IKVM.StubGen.RuntimeVisibleAnnotationsAttribute(writer);
+ annot.Add(new object[] {
+ AnnotationDefaultAttribute.TAG_ANNOTATION,
+ "Ljava/lang/annotation/Retention;",
+ "value",
+ new object[] { AnnotationDefaultAttribute.TAG_ENUM, "Ljava/lang/annotation/RetentionPolicy;", "RUNTIME" }
+ });
+ AttributeTargets validOn = attributeAnnotation.AttributeTargets;
+ List<object[]> targets = new List<object[]>();
+ if ((validOn & (AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Delegate | AttributeTargets.Assembly)) != 0)
+ {
+ targets.Add(new object[] { AnnotationDefaultAttribute.TAG_ENUM, "Ljava/lang/annotation/ElementType;", "TYPE" });
+ }
+ if ((validOn & AttributeTargets.Constructor) != 0)
+ {
+ targets.Add(new object[] { AnnotationDefaultAttribute.TAG_ENUM, "Ljava/lang/annotation/ElementType;", "CONSTRUCTOR" });
+ }
+ if ((validOn & AttributeTargets.Field) != 0)
+ {
+ targets.Add(new object[] { AnnotationDefaultAttribute.TAG_ENUM, "Ljava/lang/annotation/ElementType;", "FIELD" });
+ }
+ if ((validOn & (AttributeTargets.Method | AttributeTargets.ReturnValue)) != 0)
+ {
+ targets.Add(new object[] { AnnotationDefaultAttribute.TAG_ENUM, "Ljava/lang/annotation/ElementType;", "METHOD" });
+ }
+ if ((validOn & AttributeTargets.Parameter) != 0)
+ {
+ targets.Add(new object[] { AnnotationDefaultAttribute.TAG_ENUM, "Ljava/lang/annotation/ElementType;", "PARAMETER" });
+ }
+ annot.Add(new object[] {
+ AnnotationDefaultAttribute.TAG_ANNOTATION,
+ "Ljava/lang/annotation/Target;",
+ "value",
+ new object[] { AnnotationDefaultAttribute.TAG_ARRAY, targets.ToArray() }
+ });
+ writer.AddAttribute(annot);
+ }
+ }
+
+ private static byte[] GetAnnotationDefault(IKVM.StubGen.ClassFileWriter classFile, TypeWrapper type)
+ {
+ MemoryStream mem = new MemoryStream();
+ IKVM.StubGen.BigEndianStream bes = new IKVM.StubGen.BigEndianStream(mem);
+ if (type == PrimitiveTypeWrapper.BOOLEAN)
+ {
+ bes.WriteByte((byte)'Z');
+ bes.WriteUInt16(classFile.AddInt(0));
+ }
+ else if (type == PrimitiveTypeWrapper.BYTE)
+ {
+ bes.WriteByte((byte)'B');
+ bes.WriteUInt16(classFile.AddInt(0));
+ }
+ else if (type == PrimitiveTypeWrapper.CHAR)
+ {
+ bes.WriteByte((byte)'C');
+ bes.WriteUInt16(classFile.AddInt(0));
+ }
+ else if (type == PrimitiveTypeWrapper.SHORT)
+ {
+ bes.WriteByte((byte)'S');
+ bes.WriteUInt16(classFile.AddInt(0));
+ }
+ else if (type == PrimitiveTypeWrapper.INT)
+ {
+ bes.WriteByte((byte)'I');
+ bes.WriteUInt16(classFile.AddInt(0));
+ }
+ else if (type == PrimitiveTypeWrapper.FLOAT)
+ {
+ bes.WriteByte((byte)'F');
+ bes.WriteUInt16(classFile.AddFloat(0));
+ }
+ else if (type == PrimitiveTypeWrapper.LONG)
+ {
+ bes.WriteByte((byte)'J');
+ bes.WriteUInt16(classFile.AddLong(0));
+ }
+ else if (type == PrimitiveTypeWrapper.DOUBLE)
+ {
+ bes.WriteByte((byte)'D');
+ bes.WriteUInt16(classFile.AddDouble(0));
+ }
+ else if (type == CoreClasses.java.lang.String.Wrapper)
+ {
+ bes.WriteByte((byte)'s');
+ bes.WriteUInt16(classFile.AddUtf8(""));
+ }
+ else if ((type.Modifiers & Modifiers.Enum) != 0)
+ {
+ bes.WriteByte((byte)'e');
+ bes.WriteUInt16(classFile.AddUtf8("L" + type.Name.Replace('.', '/') + ";"));
+ bes.WriteUInt16(classFile.AddUtf8("__unspecified"));
+ }
+ else if (type == CoreClasses.java.lang.Class.Wrapper)
+ {
+ bes.WriteByte((byte)'c');
+ bes.WriteUInt16(classFile.AddUtf8("Likvm/internal/__unspecified;"));
+ }
+ else if (type.IsArray)
+ {
+ bes.WriteByte((byte)'[');
+ bes.WriteUInt16(0);
+ }
+ else
+ {
+ throw new InvalidOperationException();
+ }
+ return mem.ToArray();
+ }
+
+ private static byte[] GetAnnotationDefault(IKVM.StubGen.ClassFileWriter classFile, CustomAttributeTypedArgument value)
+ {
+ MemoryStream mem = new MemoryStream();
+ IKVM.StubGen.BigEndianStream bes = new IKVM.StubGen.BigEndianStream(mem);
+ try
+ {
+ WriteAnnotationElementValue(classFile, bes, value);
+ }
+ catch (InvalidCastException)
+ {
+ Console.Error.WriteLine("Warning: incorrect annotation default value");
+ }
+ catch (IndexOutOfRangeException)
+ {
+ Console.Error.WriteLine("Warning: incorrect annotation default value");
+ }
+ return mem.ToArray();
+ }
+
+ private static void WriteAnnotationElementValue(IKVM.StubGen.ClassFileWriter classFile, IKVM.StubGen.BigEndianStream bes, CustomAttributeTypedArgument value)
+ {
+ if (value.ArgumentType == Types.Boolean)
+ {
+ bes.WriteByte((byte)'Z');
+ bes.WriteUInt16(classFile.AddInt((bool)value.Value ? 1 : 0));
+ }
+ else if (value.ArgumentType == Types.Byte)
+ {
+ bes.WriteByte((byte)'B');
+ bes.WriteUInt16(classFile.AddInt((byte)value.Value));
+ }
+ else if (value.ArgumentType == Types.Char)
+ {
+ bes.WriteByte((byte)'C');
+ bes.WriteUInt16(classFile.AddInt((char)value.Value));
+ }
+ else if (value.ArgumentType == Types.Int16)
+ {
+ bes.WriteByte((byte)'S');
+ bes.WriteUInt16(classFile.AddInt((short)value.Value));
+ }
+ else if (value.ArgumentType == Types.Int32)
+ {
+ bes.WriteByte((byte)'I');
+ bes.WriteUInt16(classFile.AddInt((int)value.Value));
+ }
+ else if (value.ArgumentType == Types.Single)
+ {
+ bes.WriteByte((byte)'F');
+ bes.WriteUInt16(classFile.AddFloat((float)value.Value));
+ }
+ else if (value.ArgumentType == Types.Int64)
+ {
+ bes.WriteByte((byte)'J');
+ bes.WriteUInt16(classFile.AddLong((long)value.Value));
+ }
+ else if (value.ArgumentType == Types.Double)
+ {
+ bes.WriteByte((byte)'D');
+ bes.WriteUInt16(classFile.AddDouble((double)value.Value));
+ }
+ else if (value.ArgumentType == Types.String)
+ {
+ bes.WriteByte((byte)'s');
+ bes.WriteUInt16(classFile.AddUtf8((string)value.Value));
+ }
+ else if (value.ArgumentType == Types.Object.MakeArrayType())
+ {
+ CustomAttributeTypedArgument[] array = (CustomAttributeTypedArgument[])value.Value;
+ byte type = (byte)array[0].Value;
+ if (type == AnnotationDefaultAttribute.TAG_ARRAY)
+ {
+ bes.WriteByte((byte)'[');
+ bes.WriteUInt16((ushort)(array.Length - 1));
+ for (int i = 1; i < array.Length; i++)
+ {
+ WriteAnnotationElementValue(classFile, bes, array[i]);
+ }
+ }
+ else if (type == AnnotationDefaultAttribute.TAG_CLASS)
+ {
+ bes.WriteByte((byte)'c');
+ bes.WriteUInt16(classFile.AddUtf8((string)array[1].Value));
+ }
+ else if (type == AnnotationDefaultAttribute.TAG_ENUM)
+ {
+ bes.WriteByte((byte)'e');
+ bes.WriteUInt16(classFile.AddUtf8((string)array[1].Value));
+ bes.WriteUInt16(classFile.AddUtf8((string)array[2].Value));
+ }
+ else if (type == AnnotationDefaultAttribute.TAG_ANNOTATION)
+ {
+ bes.WriteByte((byte)'@');
+ bes.WriteUInt16(classFile.AddUtf8((string)array[1].Value));
+ bes.WriteUInt16((ushort)((array.Length - 2) / 2));
+ for (int i = 2; i < array.Length; i += 2)
+ {
+ bes.WriteUInt16(classFile.AddUtf8((string)array[i].Value));
+ WriteAnnotationElementValue(classFile, bes, array[i + 1]);
+ }
+ }
+ else
+ {
+ Console.Error.WriteLine("Warning: incorrect annotation default element tag: " + type);
+ }
+ }
+ else
+ {
+ Console.Error.WriteLine("Warning: incorrect annotation default element type: " + value.ArgumentType);
+ }
+ }
+ }
+}
diff --git a/runtime/vfs.cs b/runtime/vfs.cs
index 04944b37..8db1165e 100644
--- a/runtime/vfs.cs
+++ b/runtime/vfs.cs
@@ -575,7 +575,10 @@ namespace IKVM.Internal
#if !FIRST_PASS
if (buf == null)
{
- buf = ikvm.@internal.stubgen.StubGenerator.generateStub(tw.ClassObject);
+ System.IO.MemoryStream mem = new System.IO.MemoryStream();
+ bool includeNonPublicInterfaces = !"true".Equals(java.lang.Props.props.getProperty("ikvm.stubgen.skipNonPublicInterfaces"), StringComparison.OrdinalIgnoreCase);
+ IKVM.StubGen.StubGenerator.WriteClass(mem, tw, includeNonPublicInterfaces, false, false);
+ buf = mem.ToArray();
}
#endif
}