This commit is contained in:
jfrijters 2003-08-26 11:24:17 +00:00
Родитель 9d6bf7d010
Коммит fe26cb0cde
8 изменённых файлов: 113 добавлений и 23 удалений

Просмотреть файл

@ -305,7 +305,24 @@ class ClassLoaderWrapper
// HACK if the name contains a comma, we assume it is an assembly qualified name
if(name.IndexOf(',') != -1)
{
// NOTE even though we search all loaded assemblies below, we still need to do this,
// because this call might actually trigger the load of an assembly.
Type t = Type.GetType(name);
if(t == null)
{
// HACK we explicitly try all loaded assemblies, to support assemblies
// that aren't loaded in the "Load" context.
string typeName = name.Substring(0, name.IndexOf(','));
foreach(Assembly asm in AppDomain.CurrentDomain.GetAssemblies())
{
t = asm.GetType(typeName);
if(t != null && t.AssemblyQualifiedName == name)
{
break;
}
t = null;
}
}
if(t != null)
{
if(t.Assembly.IsDefined(typeof(JavaAssemblyAttribute), false))

Просмотреть файл

@ -135,7 +135,7 @@ class MemberWrapper
}
}
sealed class MethodWrapper : MemberWrapper
class MethodWrapper : MemberWrapper
{
private MethodDescriptor md;
private MethodBase originalMethod;
@ -419,7 +419,7 @@ sealed class MethodWrapper : MemberWrapper
}
}
internal object Invoke(object obj, object[] args, bool nonVirtual)
internal virtual object Invoke(object obj, object[] args, bool nonVirtual)
{
// TODO instead of looking up the method using reflection, we should use the method object passed into the
// constructor

Просмотреть файл

@ -4055,6 +4055,57 @@ class DotNetTypeWrapper : TypeWrapper
this.type = type;
}
private class DelegateMethodWrapper : MethodWrapper
{
internal DelegateMethodWrapper(TypeWrapper declaringType, MethodDescriptor md)
: base(declaringType, md, null, null, Modifiers.Public, false)
{
}
internal override object Invoke(object obj, object[] args, bool nonVirtual)
{
// TODO map exceptions
return Delegate.CreateDelegate(DeclaringType.Type, args[0], "Invoke");
}
}
private class ByRefMethodWrapper : MethodWrapper
{
private bool[] byrefs;
internal ByRefMethodWrapper(bool[] byrefs, TypeWrapper declaringType, MethodDescriptor md, MethodBase originalMethod, MethodBase method, Modifiers modifiers, bool hideFromReflection)
: base(declaringType, md, originalMethod, method, modifiers, hideFromReflection)
{
this.byrefs = byrefs;
}
internal override object Invoke(object obj, object[] args, bool nonVirtual)
{
object[] newargs = (object[])args.Clone();
for(int i = 0; i < newargs.Length; i++)
{
if(byrefs[i])
{
newargs[i] = ((Array)args[i]).GetValue(0);
}
}
try
{
return base.Invoke(obj, newargs, nonVirtual);
}
finally
{
for(int i = 0; i < newargs.Length; i++)
{
if(byrefs[i])
{
((Array)args[i]).SetValue(newargs[i], 0);
}
}
}
}
}
private void LazyPublishMembers()
{
// special support for enums
@ -4105,8 +4156,7 @@ class DotNetTypeWrapper : TypeWrapper
Debug.Assert(iface is CompiledTypeWrapper);
iface.Finish();
MethodDescriptor md = MethodDescriptor.FromNameSig(GetClassLoader(), "<init>", "(" + iface.SigName + ")V");
// TODO set method flags
MethodWrapper method = new MethodWrapper(this, md, null, null, Modifiers.Public, false);
MethodWrapper method = new DelegateMethodWrapper(this, md);
method.EmitNewobj = new DelegateConstructorEmitter(type.GetConstructor(new Type[] { typeof(object), typeof(IntPtr) }), iface.Type.GetMethod("Invoke"));
AddMethod(method);
innerClasses = new TypeWrapper[] { iface };
@ -4158,6 +4208,12 @@ class DotNetTypeWrapper : TypeWrapper
if(type.IsByRef)
{
type = type.Assembly.GetType(type.GetElementType().FullName + "[]", true);
if(mb.IsAbstract)
{
// Since we cannot override methods with byref arguments, we don't report abstract
// methods with byref args.
return null;
}
}
TypeWrapper tw = ClassLoaderWrapper.GetWrapperFromType(type);
args[i + bias] = tw;
@ -4187,7 +4243,7 @@ class DotNetTypeWrapper : TypeWrapper
else
{
Type type = ((MethodInfo)mb).ReturnType;
if(type.IsPointer)
if(type.IsPointer || type.IsByRef)
{
return null;
}
@ -4332,11 +4388,17 @@ class DotNetTypeWrapper : TypeWrapper
ParameterInfo[] parameters = mb.GetParameters();
Type[] args = new Type[parameters.Length];
bool hasByRefArgs = false;
bool[] byrefs = null;
for(int i = 0; i < parameters.Length; i++)
{
args[i] = parameters[i].ParameterType;
if(parameters[i].ParameterType.IsByRef)
{
if(byrefs == null)
{
byrefs = new bool[args.Length];
}
byrefs[i] = true;
hasByRefArgs = true;
}
}
@ -4347,7 +4409,12 @@ class DotNetTypeWrapper : TypeWrapper
mods |= Modifiers.Static;
mods &= ~Modifiers.Final;
}
MethodWrapper method = new MethodWrapper(this, md, mb, null, mods, false);
if(hasByRefArgs && !(mb is ConstructorInfo) && !mb.IsStatic)
{
mods |= Modifiers.Final;
}
MethodWrapper method = hasByRefArgs ?
new ByRefMethodWrapper(byrefs, this, md, mb, null, mods, false) : new MethodWrapper(this, md, mb, null, mods, false);
if(mb is ConstructorInfo)
{
if(isRemapped)

Двоичные данные
classpath/System.Xml.jar

Двоичный файл не отображается.

Двоичные данные
classpath/System.jar

Двоичный файл не отображается.

Просмотреть файл

@ -22,7 +22,6 @@ C:\classpath\gnu\java\awt\BitMaskExtent.java
C:\classpath\gnu\java\awt\Buffers.java
C:\classpath\gnu\java\awt\ComponentDataBlitOp.java
C:\classpath\gnu\java\awt\EventModifier.java
C:\classpath\gnu\java\awt\GLightweightPeer.java
C:\classpath\gnu\java\awt\image\GdkPixbufDecoder.java
C:\classpath\gnu\java\awt\image\ImageDecoder.java
C:\classpath\gnu\java\awt\image\XBMDecoder.java

Двоичные данные
classpath/mscorlib.jar

Двоичный файл не отображается.

Просмотреть файл

@ -36,9 +36,25 @@ public class NetExp
public static void Main(string[] args)
{
Assembly assembly = null;
if(new FileInfo(args[0]).Exists)
FileInfo file = new FileInfo(args[0]);
if(file.Exists)
{
assembly = Assembly.LoadFrom(args[0]);
try
{
// If the same assembly can be found in the "Load" context, we prefer to use that
// http://blogs.gotdotnet.com/suzcook/permalink.aspx/d5c5e14a-3612-4af1-a9b7-0a144c8dbf16
// We use AssemblyName.FullName, because otherwise the assembly will be loaded in the
// "LoadFrom" context using the path inside the AssemblyName object.
assembly = Assembly.Load(AssemblyName.GetAssemblyName(args[0]).FullName);
Console.Error.WriteLine("Warning: Assembly loaded from {0} instead", assembly.Location);
}
catch
{
}
if(assembly == null)
{
assembly = Assembly.LoadFrom(args[0]);
}
}
else
{
@ -53,7 +69,7 @@ public class NetExp
zipFile = new ZipOutputStream(new FileStream(assembly.GetName().Name + ".jar", FileMode.Create));
// HACK if we're doing the "classpath" assembly, also include the remapped types
// java.lang.Object and java.lang.Throwable are automatic, because of the $OverrideStub
if(args[0] == "classpath")
if(assembly.GetType("java.lang.Object$OverrideStub") != null)
{
ProcessClass(assembly.FullName, Class.forName("java.lang.String"), null);
ProcessClass(assembly.FullName, Class.forName("java.lang.Comparable"), null);
@ -72,23 +88,13 @@ public class NetExp
c.Write(zipFile);
}
private class MyClassLoader : ClassLoader
{
public Class loadClass(Type type)
{
return base.loadClass(type.AssemblyQualifiedName);
}
}
private static void ProcessAssembly(Assembly assembly)
{
// HACK we use our own class loader to prevent class initialization
MyClassLoader loader = new MyClassLoader();
foreach(Type t in assembly.GetTypes())
{
if(t.IsPublic)
{
ProcessClass(assembly.FullName, loader.loadClass(t), null);
ProcessClass(assembly.FullName, Class.forName(t.AssemblyQualifiedName, false, null), null);
}
}
}
@ -159,8 +165,9 @@ public class NetExp
if((mods & (Modifiers.Public | Modifiers.Protected)) != 0)
{
object constantValue = null;
// HACK we only look for constants on static final fields, to trigger less static initializers
if((mods & (Modifiers.Final | Modifiers.Static)) == (Modifiers.Final | Modifiers.Static))
// HACK we only look for constants on potential constant fields, to trigger less static initializers
if((mods & (Modifiers.Final | Modifiers.Static)) == (Modifiers.Final | Modifiers.Static) &&
(fields[i].getType().isPrimitive() || fields[i].getType() == Class.forName("java.lang.String")))
{
// HACK we use a non-standard API to get constant value
// NOTE we can't use Field.get() because that will run the static initializer and