зеркало из https://github.com/mono/ikvm-fork.git
*** empty log message ***
This commit is contained in:
Родитель
62f7fb1d43
Коммит
744fef138d
|
@ -49,7 +49,7 @@ using System.Runtime.CompilerServices;
|
|||
// You can specify all the values or you can default the Revision and Build Numbers
|
||||
// by using the '*' as shown below:
|
||||
|
||||
[assembly: AssemblyVersion("0.10.0.1")]
|
||||
[assembly: AssemblyVersion("0.11.*")]
|
||||
|
||||
//
|
||||
// In order to sign your assembly you must specify a key to use. Refer to the
|
||||
|
|
|
@ -56,6 +56,7 @@ namespace ikvm.awt
|
|||
|
||||
public class NetToolkit : gnu.java.awt.ClasspathToolkit
|
||||
{
|
||||
internal static System.Collections.ArrayList nativeQueue = System.Collections.ArrayList.Synchronized(new System.Collections.ArrayList());
|
||||
private static java.awt.EventQueue eventQueue = new java.awt.EventQueue();
|
||||
private static volatile Form bogusForm;
|
||||
private static Delegate createControlInstance;
|
||||
|
@ -372,7 +373,7 @@ namespace ikvm.awt
|
|||
return img;
|
||||
}
|
||||
|
||||
public override java.awt.Image createImage(sbyte[] imagedata, int imageoffset, int imagelength)
|
||||
public override java.awt.Image createImage(byte[] imagedata, int imageoffset, int imagelength)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
@ -440,6 +441,42 @@ namespace ikvm.awt
|
|||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override bool nativeQueueEmpty()
|
||||
{
|
||||
return nativeQueue.Count == 0;
|
||||
}
|
||||
|
||||
public override void wakeNativeQueue()
|
||||
{
|
||||
// TODO if we're blocking in iterateNativeQueue() we should release that thread
|
||||
}
|
||||
|
||||
public override void iterateNativeQueue(java.awt.EventQueue locked, bool block)
|
||||
{
|
||||
lock(nativeQueue)
|
||||
{
|
||||
if(nativeQueue.Count > 0)
|
||||
{
|
||||
locked.postEvent((java.awt.AWTEvent)nativeQueue[0]);
|
||||
nativeQueue.RemoveAt(0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(block)
|
||||
{
|
||||
Monitor.Exit(locked);
|
||||
try
|
||||
{
|
||||
//Application.DoEvents();
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Monitor.Enter(locked);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class NetFontPeer : gnu.java.awt.peer.ClasspathFontPeer
|
||||
|
@ -469,7 +506,7 @@ namespace ikvm.awt
|
|||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override sbyte getBaselineFor(java.awt.Font param1, char param2)
|
||||
public override byte getBaselineFor(java.awt.Font param1, char param2)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
@ -660,7 +697,7 @@ namespace ikvm.awt
|
|||
|
||||
}
|
||||
|
||||
public override void drawBytes(sbyte[] param1, int param2, int param3, int param4, int param5)
|
||||
public override void drawBytes(byte[] param1, int param2, int param3, int param4, int param5)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -1346,7 +1383,8 @@ namespace ikvm.awt
|
|||
|
||||
protected void postEvent(java.awt.AWTEvent evt)
|
||||
{
|
||||
getToolkit().getSystemEventQueue().postEvent(evt);
|
||||
NetToolkit.nativeQueue.Add(evt);
|
||||
//getToolkit().getSystemEventQueue().postEvent(evt);
|
||||
}
|
||||
|
||||
public int checkImage(java.awt.Image img, int width, int height, java.awt.image.ImageObserver ob)
|
||||
|
@ -1743,7 +1781,7 @@ namespace ikvm.awt
|
|||
Console.WriteLine("NetBufferedImage: setHints");
|
||||
}
|
||||
|
||||
public void setPixels(int x, int y, int w, int h, ColorModel model, sbyte[] pixels, int off, int scansize)
|
||||
public void setPixels(int x, int y, int w, int h, ColorModel model, byte[] pixels, int off, int scansize)
|
||||
{
|
||||
Console.WriteLine("NetBufferedImage: setPixels1");
|
||||
}
|
||||
|
|
Двоичные данные
classpath/System.Xml.jar
Двоичные данные
classpath/System.Xml.jar
Двоичный файл не отображается.
Двоичные данные
classpath/System.jar
Двоичные данные
classpath/System.jar
Двоичный файл не отображается.
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,8 +1,10 @@
|
|||
<?xml version="1.0"?>
|
||||
<project name="IKVM.GNU.Classpath.dll" default="IKVM.GNU.Classpath.dll">
|
||||
<property name="Classpath.dir" value="${nant.project.basedir}/../../classpath-0.13" />
|
||||
<property name="Classpath.dir" value="${nant.project.basedir}/../../classpath" />
|
||||
<property name="pathsep" value=":" />
|
||||
<property overwrite="false" name="signoption" value="" />
|
||||
<property name="jikes.compiler" value="true" />
|
||||
<property name="ecj.compiler" value="false" />
|
||||
|
||||
<if propertytrue="nant.platform.win32">
|
||||
<property name="pathsep" value=";" />
|
||||
|
@ -25,12 +27,17 @@
|
|||
<includes name="**.class"/>
|
||||
</fileset>
|
||||
</delete>
|
||||
<if propertytrue="jikes.compiler">
|
||||
<property name="classpath" value=".${pathsep}${Classpath.dir}${pathsep}${Classpath.dir}/external/w3c_dom${pathsep}${Classpath.dir}/external/sax${pathsep}${Classpath.dir}/vm/reference${pathsep}mscorlib.jar${pathsep}System.jar" />
|
||||
<exec program="jikes" commandline="-g -nowarn -classpath ${classpath} @allsources.lst"/>
|
||||
</if>
|
||||
<if propertytrue="ecj.compiler">
|
||||
<exec program="ecj" commandline="-g -1.5 -nowarn -cp mscorlib.jar${pathsep}System.jar @allsources.lst"/>
|
||||
</if>
|
||||
</target>
|
||||
|
||||
<target name="IKVM.GNU.Classpath.dll" depends="classes">
|
||||
<exec program="${nant.project.basedir}/../bin/ikvmc.exe" useruntimeengine="true" commandline="-version:0.10.0.1 ${signoption} -monoBugWorkaround -opt:fields -nojni -out:IKVM.GNU.Classpath.dll -remap:map.xml -exclude:exclude.lst -target:library -recurse:./*.class -recurse:${Classpath.dir}/*.class -recurse:${Classpath.dir}/*.properties -recurse:${Classpath.dir}/resource/*.properties mscorlib.jar System.jar System.Xml.jar -resource:lib/security/classpath.security=classpath.security" />
|
||||
<exec program="${nant.project.basedir}/../bin/ikvmc.exe" useruntimeengine="true" commandline="-version:0.11.* ${signoption} -monoBugWorkaround -opt:fields -nojni -out:IKVM.GNU.Classpath.dll -remap:map.xml -exclude:exclude.lst -target:library -recurse:./*.class -recurse:${Classpath.dir}/*.class -recurse:${Classpath.dir}/resource/*.properties mscorlib.jar System.jar System.Xml.jar -resource:lib/security/classpath.security=classpath.security" />
|
||||
<copy file="IKVM.GNU.Classpath.dll" tofile="../bin/IKVM.GNU.Classpath.dll.new" />
|
||||
<if propertytrue="nant.platform.win32">
|
||||
<call target="peverify-classpath"/>
|
||||
|
|
|
@ -45,7 +45,7 @@ public interface Configuration
|
|||
{
|
||||
// TODO
|
||||
String CLASSPATH_HOME = "";
|
||||
String CLASSPATH_VERSION = "0.13";
|
||||
String CLASSPATH_VERSION = "0.13+cvs";
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
Copyright (C) 2005 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 gnu.classpath;
|
||||
|
||||
import cli.System.Diagnostics.StackFrame;
|
||||
import cli.System.Diagnostics.StackTrace;
|
||||
|
||||
public final class VMStackWalker
|
||||
{
|
||||
private static final int SKIP_FRAMES = 2;
|
||||
private static final cli.System.Reflection.Assembly mscorlib = cli.System.Type.GetType("System.Object").get_Assembly();
|
||||
private static final cli.System.Type methodType = cli.System.Type.GetType("java.lang.reflect.Method");
|
||||
private static final cli.System.Type constructorType = cli.System.Type.GetType("java.lang.reflect.Constructor");
|
||||
private static final cli.System.Type jniEnvType = getJNIEnvType();
|
||||
|
||||
public static Class[] getClassContext()
|
||||
{
|
||||
StackTrace stack = new StackTrace(SKIP_FRAMES);
|
||||
java.util.ArrayList list = new java.util.ArrayList();
|
||||
for(int i = 0; i < stack.get_FrameCount(); i++)
|
||||
{
|
||||
StackFrame frame = stack.GetFrame(i);
|
||||
// TODO handle reflection scenarios
|
||||
cli.System.Type type = frame.GetMethod().get_DeclaringType();
|
||||
if(type != null)
|
||||
{
|
||||
list.add(getClassFromType(type));
|
||||
}
|
||||
}
|
||||
Class[] classes = new Class[list.size()];
|
||||
list.toArray(classes);
|
||||
return classes;
|
||||
}
|
||||
|
||||
public static Class getCallingClass()
|
||||
{
|
||||
StackFrame frame = new StackFrame(SKIP_FRAMES);
|
||||
cli.System.Type type = frame.GetMethod().get_DeclaringType();
|
||||
if(isReflectionCaller(type))
|
||||
{
|
||||
type = getRealCaller(new StackTrace(SKIP_FRAMES + 1));
|
||||
}
|
||||
if(type != null)
|
||||
{
|
||||
return (Class)getClassFromType(type);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ClassLoader getCallingClassLoader()
|
||||
{
|
||||
StackFrame frame = new StackFrame(SKIP_FRAMES);
|
||||
cli.System.Type type = frame.GetMethod().get_DeclaringType();
|
||||
if(isReflectionCaller(type))
|
||||
{
|
||||
type = getRealCaller(new StackTrace(SKIP_FRAMES + 1));
|
||||
}
|
||||
if(type != null)
|
||||
{
|
||||
return (ClassLoader)getClassLoaderFromType(type);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean isReflectionCaller(cli.System.Type type)
|
||||
{
|
||||
if(type != null)
|
||||
{
|
||||
cli.System.Reflection.Assembly asm = type.get_Assembly();
|
||||
// if we're being called by mscorlib, that means that reflection was used
|
||||
return asm == mscorlib || asm == getNonVirtualInvokeAssembly();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static cli.System.Type getRealCaller(StackTrace stack)
|
||||
{
|
||||
for(int i = 0; i < stack.get_FrameCount(); i++)
|
||||
{
|
||||
cli.System.Type type = stack.GetFrame(i).GetMethod().get_DeclaringType();
|
||||
if(type == methodType || type == constructorType || type == jniEnvType)
|
||||
{
|
||||
while(++i < stack.get_FrameCount() && (type == methodType || type == constructorType || type == jniEnvType))
|
||||
{
|
||||
type = stack.GetFrame(i).GetMethod().get_DeclaringType();
|
||||
}
|
||||
if(type == null || i >= stack.get_FrameCount())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
// If the reflection method was invoked by reflection, continue going up the stack.
|
||||
if(isReflectionCaller(type))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static native Object getClassFromType(cli.System.Type type);
|
||||
private static native Object getClassLoaderFromType(cli.System.Type type);
|
||||
private static native cli.System.Reflection.Assembly getNonVirtualInvokeAssembly();
|
||||
private static native cli.System.Type getJNIEnvType();
|
||||
}
|
|
@ -49,7 +49,6 @@ import cli.System.Net.Sockets.SocketType;
|
|||
import cli.System.Net.Sockets.ProtocolType;
|
||||
import cli.System.Net.Sockets.AddressFamily;
|
||||
import ikvm.lang.CIL;
|
||||
import ikvm.lang.ByteArrayHack;
|
||||
|
||||
/**
|
||||
* This is the default socket implementation for datagram sockets.
|
||||
|
@ -166,7 +165,7 @@ public class PlainDatagramSocketImpl extends DatagramSocketImpl
|
|||
{
|
||||
throw new SocketException("Invalid port");
|
||||
}
|
||||
if(socket.SendTo(ByteArrayHack.cast(packet.getData()), packet.getOffset(), len, SocketFlags.wrap(SocketFlags.None), new IPEndPoint(PlainSocketImpl.getAddressFromInetAddress(packet.getAddress()), port)) != len)
|
||||
if(socket.SendTo(packet.getData(), packet.getOffset(), len, SocketFlags.wrap(SocketFlags.None), new IPEndPoint(PlainSocketImpl.getAddressFromInetAddress(packet.getAddress()), port)) != len)
|
||||
{
|
||||
throw new SocketException("Not all data was sent");
|
||||
}
|
||||
|
@ -211,7 +210,7 @@ public class PlainDatagramSocketImpl extends DatagramSocketImpl
|
|||
{
|
||||
if(false) throw new cli.System.Net.Sockets.SocketException();
|
||||
if(false) throw new cli.System.ObjectDisposedException("");
|
||||
int length = socket.ReceiveFrom(ByteArrayHack.cast(data), packet.getOffset(), getDatagramPacketBufferLength(packet),
|
||||
int length = socket.ReceiveFrom(data, packet.getOffset(), getDatagramPacketBufferLength(packet),
|
||||
cli.System.Net.Sockets.SocketFlags.wrap(cli.System.Net.Sockets.SocketFlags.None), remoteEP);
|
||||
setDatagramPacketLength(packet, length);
|
||||
}
|
||||
|
|
|
@ -51,7 +51,6 @@ import cli.System.Net.Sockets.ProtocolType;
|
|||
import cli.System.Net.Sockets.AddressFamily;
|
||||
import cli.System.Net.Sockets.SocketShutdown;
|
||||
import ikvm.lang.CIL;
|
||||
import ikvm.lang.ByteArrayHack;
|
||||
|
||||
/**
|
||||
* Unless the application installs its own SocketImplFactory, this is the
|
||||
|
@ -341,7 +340,7 @@ public class PlainSocketImpl extends SocketImpl
|
|||
{
|
||||
if(false) throw new cli.System.Net.Sockets.SocketException();
|
||||
if(false) throw new cli.System.ObjectDisposedException("");
|
||||
return socket.Receive(ByteArrayHack.cast(buf), offset, len, SocketFlags.wrap(SocketFlags.None));
|
||||
return socket.Receive(buf, offset, len, SocketFlags.wrap(SocketFlags.None));
|
||||
}
|
||||
catch(cli.System.Net.Sockets.SocketException x)
|
||||
{
|
||||
|
@ -371,7 +370,7 @@ public class PlainSocketImpl extends SocketImpl
|
|||
{
|
||||
if(false) throw new cli.System.Net.Sockets.SocketException();
|
||||
if(false) throw new cli.System.ObjectDisposedException("");
|
||||
socket.Send(ByteArrayHack.cast(buf), offset, len, SocketFlags.wrap(SocketFlags.None));
|
||||
socket.Send(buf, offset, len, SocketFlags.wrap(SocketFlags.None));
|
||||
}
|
||||
catch(cli.System.Net.Sockets.SocketException x)
|
||||
{
|
||||
|
@ -667,7 +666,7 @@ public class PlainSocketImpl extends SocketImpl
|
|||
if(false) throw new cli.System.Net.Sockets.SocketException();
|
||||
if(false) throw new cli.System.ObjectDisposedException("");
|
||||
byte[] oob = { (byte)data };
|
||||
socket.Send(ByteArrayHack.cast(oob), SocketFlags.wrap(SocketFlags.OutOfBand));
|
||||
socket.Send(oob, SocketFlags.wrap(SocketFlags.OutOfBand));
|
||||
}
|
||||
catch(cli.System.Net.Sockets.SocketException x)
|
||||
{
|
||||
|
|
|
@ -81,20 +81,28 @@ class IkvmresURLConnection extends URLConnection
|
|||
}
|
||||
try
|
||||
{
|
||||
ResourceReader r = new ResourceReader(s);
|
||||
Object r;
|
||||
try
|
||||
{
|
||||
IEnumerator e = r.GetEnumerator();
|
||||
r = ResourceReader.class.getConstructor(new Class[] { cli.System.IO.Stream.class }).newInstance(new Object[] { s });
|
||||
}
|
||||
catch(Exception x)
|
||||
{
|
||||
throw (IOException)new IOException().initCause(x);
|
||||
}
|
||||
try
|
||||
{
|
||||
IEnumerator e = ((IEnumerable)r).GetEnumerator();
|
||||
if(!e.MoveNext())
|
||||
{
|
||||
throw new IOException("invalid resource " + resource + " found in assembly " + assembly);
|
||||
}
|
||||
inputStream = new ByteArrayInputStream(ikvm.lang.ByteArrayHack.cast((cli.System.Byte[])((DictionaryEntry)e.get_Current()).get_Value()));
|
||||
inputStream = new ByteArrayInputStream((byte[])((DictionaryEntry)e.get_Current()).get_Value());
|
||||
connected = true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
r.Close();
|
||||
((cli.System.IDisposable)r).Dispose();
|
||||
}
|
||||
}
|
||||
finally
|
||||
|
|
|
@ -55,7 +55,6 @@ import java.nio.channels.WritableByteChannel;
|
|||
|
||||
import cli.System.Console;
|
||||
import cli.System.IO.*;
|
||||
import ikvm.lang.ByteArrayHack;
|
||||
import ikvm.lang.CIL;
|
||||
|
||||
/**
|
||||
|
@ -382,7 +381,7 @@ public final class FileChannelImpl extends FileChannel
|
|||
try
|
||||
{
|
||||
if(false) throw new cli.System.IO.IOException();
|
||||
int count = stream.Read(ByteArrayHack.cast(buf), offset, len);
|
||||
int count = stream.Read(buf, offset, len);
|
||||
if(count == 0)
|
||||
{
|
||||
count = -1;
|
||||
|
@ -416,6 +415,7 @@ public final class FileChannelImpl extends FileChannel
|
|||
{
|
||||
byte[] buffer = src.array();
|
||||
write(buffer, src.arrayOffset() + src.position(), len);
|
||||
src.position(src.position() + len);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -468,7 +468,7 @@ public final class FileChannelImpl extends FileChannel
|
|||
{
|
||||
if(false) throw new cli.System.IO.IOException();
|
||||
if(false) throw new cli.System.ObjectDisposedException(null);
|
||||
stream.Write(ByteArrayHack.cast(buf), offset, len);
|
||||
stream.Write(buf, offset, len);
|
||||
// NOTE FileStream buffers the output, so we have to flush explicitly
|
||||
stream.Flush();
|
||||
}
|
||||
|
@ -491,7 +491,7 @@ public final class FileChannelImpl extends FileChannel
|
|||
{
|
||||
if(false) throw new cli.System.IO.IOException();
|
||||
if(false) throw new cli.System.ObjectDisposedException(null);
|
||||
stream.WriteByte(CIL.box_ubyte((byte)b));
|
||||
stream.WriteByte((byte)b);
|
||||
// NOTE FileStream buffers the output, so we have to flush explicitly
|
||||
stream.Flush();
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ public interface LibraryVMInterface
|
|||
|
||||
void jniWaitUntilLastThread();
|
||||
void jniDetach();
|
||||
void setThreadGroup(Object group);
|
||||
|
||||
Object newConstructor(Object clazz, Object wrapper);
|
||||
Object newMethod(Object clazz, Object wrapper);
|
||||
|
|
|
@ -1,9 +1,35 @@
|
|||
/*
|
||||
Copyright (C) 2003, 2004, 2005 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.lang;
|
||||
|
||||
/** @deprecated */
|
||||
public final class ByteArrayHack
|
||||
{
|
||||
private ByteArrayHack() {}
|
||||
|
||||
public static native cli.System.Byte[] cast(byte[] b);
|
||||
public static native byte[] cast(cli.System.Byte[] b);
|
||||
public static byte[] cast(byte[] b)
|
||||
{
|
||||
return b;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2003, 2004 Jeroen Frijters
|
||||
Copyright (C) 2003, 2004, 2005 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
|
||||
|
@ -43,12 +43,12 @@ public class CIL
|
|||
public static native Object box_long(long v);
|
||||
public static native Object box_double(double v);
|
||||
|
||||
public static native cli.System.Byte box_ubyte(byte v);
|
||||
public static native cli.System.SByte box_sbyte(byte v);
|
||||
public static native cli.System.UInt16 box_ushort(short v);
|
||||
public static native cli.System.UInt32 box_uint(int v);
|
||||
public static native cli.System.UInt64 box_ulong(long v);
|
||||
|
||||
public static native byte unbox_ubyte(cli.System.Byte v);
|
||||
public static native byte unbox_sbyte(cli.System.SByte v);
|
||||
public static native short unbox_ushort(cli.System.UInt16 v);
|
||||
public static native int unbox_uint(cli.System.UInt32 v);
|
||||
public static native long unbox_ulong(cli.System.UInt64 v);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2004 Jeroen Frijters
|
||||
Copyright (C) 2004, 2005 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
|
||||
|
@ -91,7 +91,7 @@ class LibraryVMInterfaceImpl implements ikvm.internal.LibraryVMInterface
|
|||
|
||||
public Object box(Object val)
|
||||
{
|
||||
if(val instanceof cli.System.SByte)
|
||||
if(val instanceof cli.System.Byte)
|
||||
{
|
||||
return new Byte(CIL.unbox_byte(val));
|
||||
}
|
||||
|
@ -189,12 +189,17 @@ class LibraryVMInterfaceImpl implements ikvm.internal.LibraryVMInterface
|
|||
VMThread.jniDetach();
|
||||
}
|
||||
|
||||
public void setThreadGroup(Object group)
|
||||
{
|
||||
VMThread.setThreadGroup((ThreadGroup)group);
|
||||
}
|
||||
|
||||
public native Object newDirectByteBuffer(cli.System.IntPtr address, int capacity);
|
||||
public native cli.System.IntPtr getDirectBufferAddress(Object buffer);
|
||||
|
||||
public int getDirectBufferCapacity(Object buffer)
|
||||
{
|
||||
return ((java.nio.ByteBuffer)buffer).capacity();
|
||||
return ((java.nio.Buffer)buffer).capacity();
|
||||
}
|
||||
|
||||
public void setProperties(cli.System.Collections.Hashtable props)
|
||||
|
|
|
@ -45,6 +45,7 @@ import java.util.Enumeration;
|
|||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.StringTokenizer;
|
||||
import java.lang.reflect.Constructor;
|
||||
import gnu.classpath.SystemProperties;
|
||||
|
@ -172,6 +173,8 @@ final class VMClassLoader
|
|||
* @throws IOException if one occurs
|
||||
*/
|
||||
static Enumeration getResources(String name) throws IOException
|
||||
{
|
||||
synchronized(nestedGetResourcesHack)
|
||||
{
|
||||
if(cli.System.Threading.Thread.GetData(nestedGetResourcesHack) != null)
|
||||
{
|
||||
|
@ -199,6 +202,7 @@ final class VMClassLoader
|
|||
cli.System.Threading.Thread.SetData(nestedGetResourcesHack, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static cli.System.LocalDataStoreSlot nestedGetResourcesHack = cli.System.Threading.Thread.AllocateDataSlot();
|
||||
|
||||
|
@ -212,6 +216,14 @@ final class VMClassLoader
|
|||
*/
|
||||
static Package getPackage(String name)
|
||||
{
|
||||
Package[] packages = getPackagesImpl();
|
||||
for(int i = 0; i < packages.length; i++)
|
||||
{
|
||||
if(packages[i].getName().equals(name))
|
||||
{
|
||||
return packages[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -223,9 +235,96 @@ final class VMClassLoader
|
|||
* @return all named packages, if any exist
|
||||
*/
|
||||
static Package[] getPackages()
|
||||
{
|
||||
return (Package[])getPackagesImpl().clone();
|
||||
}
|
||||
|
||||
private static boolean runningOnMono = Type.GetType("Mono.Runtime") != null;
|
||||
|
||||
private static Package[] getPackagesImpl()
|
||||
{
|
||||
// MONOBUG Assembly.GetTypes() on IKVM.GNU.Classpath dies
|
||||
if(runningOnMono)
|
||||
{
|
||||
return new Package[0];
|
||||
}
|
||||
Package[] packages = packageCache;
|
||||
if(packages == null)
|
||||
{
|
||||
ClassLoader boot = getBootstrapClassLoader();
|
||||
if(boot != null)
|
||||
{
|
||||
synchronized(nestedGetResourcesHack)
|
||||
{
|
||||
if(cli.System.Threading.Thread.GetData(nestedGetResourcesHack) != null)
|
||||
{
|
||||
return new Package[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
HashMap h = new HashMap();
|
||||
Assembly[] assemblies = AppDomain.get_CurrentDomain().GetAssemblies();
|
||||
for(int i = 0; i < assemblies.length; i++)
|
||||
{
|
||||
if(!(assemblies[i] instanceof cli.System.Reflection.Emit.AssemblyBuilder))
|
||||
{
|
||||
Type[] types = assemblies[i].GetTypes();
|
||||
for(int j = 0; j < types.length; j++)
|
||||
{
|
||||
String name = getPackageName(types[j]);
|
||||
if(name != null)
|
||||
{
|
||||
// TODO fill out more package details
|
||||
h.put(name, new Package(name, null, null, null, null, null, null, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(boot != null)
|
||||
{
|
||||
Package[] pkgboot;
|
||||
synchronized(nestedGetResourcesHack)
|
||||
{
|
||||
cli.System.Threading.Thread.SetData(nestedGetResourcesHack, "");
|
||||
try
|
||||
{
|
||||
pkgboot = boot.getPackages();
|
||||
}
|
||||
finally
|
||||
{
|
||||
cli.System.Threading.Thread.SetData(nestedGetResourcesHack, null);
|
||||
}
|
||||
}
|
||||
Collection c = h.values();
|
||||
packages = new Package[c.size() + pkgboot.length];
|
||||
c.toArray(packages);
|
||||
VMSystem.arraycopy(pkgboot, 0, packages, c.size(), pkgboot.length);
|
||||
// we don't cache the result, because we don't know when the bootstrap class loader loads a new package
|
||||
}
|
||||
else
|
||||
{
|
||||
Collection c = h.values();
|
||||
packages = new Package[c.size()];
|
||||
c.toArray(packages);
|
||||
packageCache = packages;
|
||||
}
|
||||
}
|
||||
return packages;
|
||||
}
|
||||
|
||||
private static volatile Package[] packageCache;
|
||||
|
||||
static
|
||||
{
|
||||
AppDomain.get_CurrentDomain().add_AssemblyLoad(new AssemblyLoadEventHandler(
|
||||
new AssemblyLoadEventHandler.Method() {
|
||||
public void Invoke(Object sender, AssemblyLoadEventArgs args) {
|
||||
packageCache = null;
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private static native String getPackageName(Type type);
|
||||
|
||||
/**
|
||||
* Helper for java.lang.Integer, Byte, etc to get the TYPE class
|
||||
|
|
|
@ -189,7 +189,7 @@ final class VMRuntime
|
|||
* @param filename the file to load
|
||||
* @return 0 on failure, nonzero on success
|
||||
*/
|
||||
static native int nativeLoad(String filename);
|
||||
static native int nativeLoad(String filename, Object classLoader);
|
||||
|
||||
/**
|
||||
* Map a system-independent "short name" to the full file name.
|
||||
|
|
|
@ -161,6 +161,15 @@ final class VMThread
|
|||
}
|
||||
}
|
||||
|
||||
static void setThreadGroup(ThreadGroup group)
|
||||
{
|
||||
Thread javaThread = (Thread)cli.System.Threading.Thread.GetData(localDataStoreSlot);
|
||||
if(javaThread == null)
|
||||
{
|
||||
newThread(group);
|
||||
}
|
||||
}
|
||||
|
||||
static void create(Thread thread, long stacksize)
|
||||
{
|
||||
VMThread vmThread = new VMThread(thread);
|
||||
|
@ -463,10 +472,9 @@ final class VMThread
|
|||
}
|
||||
}
|
||||
|
||||
static Thread currentThread()
|
||||
{
|
||||
Thread javaThread = (Thread)cli.System.Threading.Thread.GetData(localDataStoreSlot);
|
||||
if(javaThread == null)
|
||||
// this method creates a new java.lang.Thread instance for threads that were started outside
|
||||
// of Java (either in .NET or in native code)
|
||||
private static Thread newThread(ThreadGroup group)
|
||||
{
|
||||
cli.System.Threading.Thread nativeThread = cli.System.Threading.Thread.get_CurrentThread();
|
||||
VMThread vmThread = new VMThread(null);
|
||||
|
@ -491,7 +499,7 @@ final class VMThread
|
|||
priority = Thread.MAX_PRIORITY;
|
||||
break;
|
||||
}
|
||||
javaThread = new Thread(vmThread, nativeThread.get_Name(), priority, nativeThread.get_IsBackground());
|
||||
Thread javaThread = new Thread(vmThread, nativeThread.get_Name(), priority, nativeThread.get_IsBackground());
|
||||
if(!javaThread.daemon)
|
||||
{
|
||||
synchronized(countLock)
|
||||
|
@ -502,11 +510,18 @@ final class VMThread
|
|||
vmThread.thread = javaThread;
|
||||
cli.System.Threading.Thread.SetData(localDataStoreSlot, javaThread);
|
||||
cli.System.Threading.Thread.SetData(cli.System.Threading.Thread.GetNamedDataSlot("ikvm-thread-hack"), new CleanupHack(javaThread));
|
||||
// HACK JNI code can attach native threads to any thread group
|
||||
ThreadGroup group = (ThreadGroup)cli.System.Threading.Thread.GetData(cli.System.Threading.Thread.GetNamedDataSlot("ikvm-thread-group"));
|
||||
javaThread.group = group == null ? ThreadGroup.root : group;
|
||||
javaThread.group = group;
|
||||
javaThread.group.addThread(javaThread);
|
||||
InheritableThreadLocal.newChildThread(javaThread);
|
||||
return javaThread;
|
||||
}
|
||||
|
||||
static Thread currentThread()
|
||||
{
|
||||
Thread javaThread = (Thread)cli.System.Threading.Thread.GetData(localDataStoreSlot);
|
||||
if(javaThread == null)
|
||||
{
|
||||
javaThread = newThread(ThreadGroup.root);
|
||||
}
|
||||
return javaThread;
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ exception statement from your version. */
|
|||
package java.lang.reflect;
|
||||
|
||||
import cli.System.Diagnostics.StackFrame;
|
||||
import gnu.classpath.VMStackWalker;
|
||||
|
||||
/**
|
||||
* The Constructor class represents a constructor of a class. It also allows
|
||||
|
@ -259,7 +260,7 @@ public final class Constructor
|
|||
InvocationTargetException
|
||||
{
|
||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
||||
Field.checkAccess(modifiers, null, declaringClass, new StackFrame(1));
|
||||
Field.checkAccess(modifiers, null, declaringClass, VMStackWalker.getCallingClass());
|
||||
int mods = declaringClass.getModifiers() | Method.GetRealModifiers(declaringClass);
|
||||
if(Modifier.isAbstract(mods) || Modifier.isInterface(mods))
|
||||
{
|
||||
|
|
|
@ -39,6 +39,7 @@ exception statement from your version. */
|
|||
package java.lang.reflect;
|
||||
|
||||
import cli.System.Diagnostics.StackFrame;
|
||||
import gnu.classpath.VMStackWalker;
|
||||
|
||||
/**
|
||||
* The Field class represents a member variable of a class. It also allows
|
||||
|
@ -236,7 +237,7 @@ public final class Field extends AccessibleObject implements Member
|
|||
throws IllegalAccessException
|
||||
{
|
||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
||||
checkAccess(modifiers, o, declaringClass, new StackFrame(1));
|
||||
checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
|
||||
return GetValue(fieldCookie, o);
|
||||
}
|
||||
private static native Object GetValue(Object fieldCookie, Object o);
|
||||
|
@ -262,7 +263,7 @@ public final class Field extends AccessibleObject implements Member
|
|||
throws IllegalAccessException
|
||||
{
|
||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
||||
checkAccess(modifiers, o, declaringClass, new StackFrame(1));
|
||||
checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
|
||||
return ((Boolean)GetValue(fieldCookie, o)).booleanValue();
|
||||
}
|
||||
|
||||
|
@ -287,7 +288,7 @@ public final class Field extends AccessibleObject implements Member
|
|||
throws IllegalAccessException
|
||||
{
|
||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
||||
checkAccess(modifiers, o, declaringClass, new StackFrame(1));
|
||||
checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
|
||||
return ((Byte)GetValue(fieldCookie, o)).byteValue();
|
||||
}
|
||||
|
||||
|
@ -310,7 +311,7 @@ public final class Field extends AccessibleObject implements Member
|
|||
throws IllegalAccessException
|
||||
{
|
||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
||||
checkAccess(modifiers, o, declaringClass, new StackFrame(1));
|
||||
checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
|
||||
return ((Character)GetValue(fieldCookie, o)).charValue();
|
||||
}
|
||||
|
||||
|
@ -335,7 +336,7 @@ public final class Field extends AccessibleObject implements Member
|
|||
throws IllegalAccessException
|
||||
{
|
||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
||||
checkAccess(modifiers, o, declaringClass, new StackFrame(1));
|
||||
checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
|
||||
return ((Short)GetValue(fieldCookie, o)).shortValue();
|
||||
}
|
||||
|
||||
|
@ -360,7 +361,7 @@ public final class Field extends AccessibleObject implements Member
|
|||
throws IllegalAccessException
|
||||
{
|
||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
||||
checkAccess(modifiers, o, declaringClass, new StackFrame(1));
|
||||
checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
|
||||
return ((Integer)GetValue(fieldCookie, o)).intValue();
|
||||
}
|
||||
|
||||
|
@ -385,7 +386,7 @@ public final class Field extends AccessibleObject implements Member
|
|||
throws IllegalAccessException
|
||||
{
|
||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
||||
checkAccess(modifiers, o, declaringClass, new StackFrame(1));
|
||||
checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
|
||||
return ((Long)GetValue(fieldCookie, o)).longValue();
|
||||
}
|
||||
|
||||
|
@ -410,7 +411,7 @@ public final class Field extends AccessibleObject implements Member
|
|||
throws IllegalAccessException
|
||||
{
|
||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
||||
checkAccess(modifiers, o, declaringClass, new StackFrame(1));
|
||||
checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
|
||||
return ((Float)GetValue(fieldCookie, o)).floatValue();
|
||||
}
|
||||
|
||||
|
@ -436,7 +437,7 @@ public final class Field extends AccessibleObject implements Member
|
|||
throws IllegalAccessException
|
||||
{
|
||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
||||
checkAccess(modifiers, o, declaringClass, new StackFrame(1));
|
||||
checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
|
||||
return ((Double)GetValue(fieldCookie, o)).doubleValue();
|
||||
}
|
||||
|
||||
|
@ -489,17 +490,16 @@ public final class Field extends AccessibleObject implements Member
|
|||
throws IllegalAccessException
|
||||
{
|
||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
||||
checkAccess(modifiers, o, declaringClass, new StackFrame(1));
|
||||
checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
|
||||
SetValue(fieldCookie, o, value);
|
||||
}
|
||||
private static native void SetValue(Object fieldCookie, Object o, Object value);
|
||||
|
||||
static void checkAccess(int modifiers, Object o, Class declaringClass, StackFrame frame) throws IllegalAccessException
|
||||
static void checkAccess(int modifiers, Object o, Class declaringClass, Class caller) throws IllegalAccessException
|
||||
{
|
||||
// when we're invoking a constructor, modifiers will not be static, but o will be null.
|
||||
Class actualClass = Modifier.isStatic(modifiers) || o == null ? declaringClass : o.getClass();
|
||||
boolean declaringClassIsPublic = (Method.GetRealModifiers(declaringClass) & Modifier.PUBLIC) != 0;
|
||||
Class caller = getClassFromFrame(frame);
|
||||
if((!Modifier.isPublic(modifiers) || !declaringClassIsPublic) && declaringClass != caller)
|
||||
{
|
||||
// if the caller is a global method, the class returned will be null
|
||||
|
@ -512,12 +512,13 @@ public final class Field extends AccessibleObject implements Member
|
|||
}
|
||||
else if(!isSamePackage(declaringClass, caller) || Modifier.isPrivate(modifiers))
|
||||
{
|
||||
throw new IllegalAccessException();
|
||||
throw new IllegalAccessException("Class " + caller.getName() +
|
||||
" can not access a member of class " + declaringClass.getName() +
|
||||
" with modifiers \"" + Modifier.toString(modifiers & (Modifier.PRIVATE | Modifier.PROTECTED)) + "\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
private static native boolean isSamePackage(Class a, Class b);
|
||||
private static native Class getClassFromFrame(StackFrame frame);
|
||||
|
||||
/**
|
||||
* Set this boolean Field. If the field is static, <code>o</code> will be
|
||||
|
@ -540,7 +541,7 @@ public final class Field extends AccessibleObject implements Member
|
|||
throws IllegalAccessException
|
||||
{
|
||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
||||
checkAccess(modifiers, o, declaringClass, new StackFrame(1));
|
||||
checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
|
||||
SetValue(fieldCookie, o, new Boolean(value));
|
||||
}
|
||||
|
||||
|
@ -565,7 +566,7 @@ public final class Field extends AccessibleObject implements Member
|
|||
throws IllegalAccessException
|
||||
{
|
||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
||||
checkAccess(modifiers, o, declaringClass, new StackFrame(1));
|
||||
checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
|
||||
SetValue(fieldCookie, o, new Byte(value));
|
||||
}
|
||||
|
||||
|
@ -590,7 +591,7 @@ public final class Field extends AccessibleObject implements Member
|
|||
throws IllegalAccessException
|
||||
{
|
||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
||||
checkAccess(modifiers, o, declaringClass, new StackFrame(1));
|
||||
checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
|
||||
SetValue(fieldCookie, o, new Character(value));
|
||||
}
|
||||
|
||||
|
@ -615,7 +616,7 @@ public final class Field extends AccessibleObject implements Member
|
|||
throws IllegalAccessException
|
||||
{
|
||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
||||
checkAccess(modifiers, o, declaringClass, new StackFrame(1));
|
||||
checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
|
||||
SetValue(fieldCookie, o, new Short(value));
|
||||
}
|
||||
|
||||
|
@ -640,7 +641,7 @@ public final class Field extends AccessibleObject implements Member
|
|||
throws IllegalAccessException
|
||||
{
|
||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
||||
checkAccess(modifiers, o, declaringClass, new StackFrame(1));
|
||||
checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
|
||||
SetValue(fieldCookie, o, new Integer(value));
|
||||
}
|
||||
|
||||
|
@ -665,7 +666,7 @@ public final class Field extends AccessibleObject implements Member
|
|||
throws IllegalAccessException
|
||||
{
|
||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
||||
checkAccess(modifiers, o, declaringClass, new StackFrame(1));
|
||||
checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
|
||||
SetValue(fieldCookie, o, new Long(value));
|
||||
}
|
||||
|
||||
|
@ -690,7 +691,7 @@ public final class Field extends AccessibleObject implements Member
|
|||
throws IllegalAccessException
|
||||
{
|
||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
||||
checkAccess(modifiers, o, declaringClass, new StackFrame(1));
|
||||
checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
|
||||
SetValue(fieldCookie, o, new Float(value));
|
||||
}
|
||||
|
||||
|
@ -715,7 +716,7 @@ public final class Field extends AccessibleObject implements Member
|
|||
throws IllegalAccessException
|
||||
{
|
||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
||||
checkAccess(modifiers, o, declaringClass, new StackFrame(1));
|
||||
checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
|
||||
SetValue(fieldCookie, o, new Double(value));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ exception statement from your version. */
|
|||
package java.lang.reflect;
|
||||
|
||||
import cli.System.Diagnostics.StackFrame;
|
||||
import gnu.classpath.VMStackWalker;
|
||||
|
||||
/**
|
||||
* The Method class represents a member method of a class. It also allows
|
||||
|
@ -336,7 +337,7 @@ public final class Method extends AccessibleObject implements Member
|
|||
throws IllegalAccessException, InvocationTargetException
|
||||
{
|
||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
||||
Field.checkAccess(modifiers, o, declaringClass, new StackFrame(1));
|
||||
Field.checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
|
||||
if(!Modifier.isStatic(modifiers))
|
||||
{
|
||||
if(o == null)
|
||||
|
|
|
@ -1,3 +1,26 @@
|
|||
/*
|
||||
Copyright (C) 2004, 2005 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 java.nio;
|
||||
|
||||
import gnu.classpath.RawData;
|
||||
|
@ -12,9 +35,9 @@ class VMDirectByteBuffer
|
|||
return new DirectByteBufferImpl.ReadWrite(null, new RawData(p), capacity, capacity, 0);
|
||||
}
|
||||
|
||||
static IntPtr GetDirectBufferAddress(ByteBuffer buf)
|
||||
static IntPtr GetDirectBufferAddress(Buffer buf)
|
||||
{
|
||||
return ((DirectByteBufferImpl)buf).address.p();
|
||||
return buf.address != null ? buf.address.p() : IntPtr.Zero;
|
||||
}
|
||||
|
||||
static RawData allocate(int capacity)
|
||||
|
@ -35,7 +58,7 @@ class VMDirectByteBuffer
|
|||
static void get(RawData r, int index, byte[] dst, int offset, int length)
|
||||
{
|
||||
IntPtr address = new IntPtr(r.p().ToInt64() + index);
|
||||
Marshal.Copy(address, ikvm.lang.ByteArrayHack.cast(dst), offset, length);
|
||||
Marshal.Copy(address, dst, offset, length);
|
||||
}
|
||||
|
||||
static void put(RawData r, int index, byte value)
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
Copyright (C) 2005 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 java.nio.channels;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStream;
|
||||
import gnu.java.nio.ChannelInputStream;
|
||||
import gnu.java.nio.ChannelOutputStream;
|
||||
import gnu.java.nio.channels.FileChannelImpl;
|
||||
|
||||
final class VMChannels
|
||||
{
|
||||
// These methods are implemented in map.xml, because they rely on a package private
|
||||
// constructor of FileInputStream and FileOutputStream.
|
||||
private static native FileInputStream newInputStream(FileChannelImpl ch);
|
||||
private static native FileOutputStream newOutputStream(FileChannelImpl ch);
|
||||
|
||||
static InputStream newInputStream(ReadableByteChannel ch)
|
||||
{
|
||||
if (ch instanceof FileChannelImpl)
|
||||
return newInputStream((FileChannelImpl)ch);
|
||||
else
|
||||
return new ChannelInputStream(ch);
|
||||
}
|
||||
|
||||
static OutputStream newOutputStream(WritableByteChannel ch)
|
||||
{
|
||||
if (ch instanceof FileChannelImpl)
|
||||
return newOutputStream((FileChannelImpl)ch);
|
||||
else
|
||||
return new ChannelOutputStream(ch);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!--
|
||||
Copyright (C) 2002, 2003, 2004 Jeroen Frijters
|
||||
Copyright (C) 2002, 2003, 2004, 2005 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
|
||||
|
@ -205,6 +205,17 @@
|
|||
<constructor sig="(Ljava.lang.StringBuffer;)V" modifiers="public">
|
||||
<redirect class="java.lang.StringHelper" name="NewString" type="static" sig="(Ljava.lang.StringBuffer;)Ljava.lang.String;" />
|
||||
</constructor>
|
||||
<constructor sig="(Ljava.lang.StringBuilder;)V" modifiers="public">
|
||||
<alternateBody>
|
||||
<ldarg_0 />
|
||||
<ldfld class="java.lang.StringBuilder" name="value" sig="[C" />
|
||||
<ldc_i4_0 />
|
||||
<ldarg_0 />
|
||||
<ldfld class="java.lang.StringBuilder" name="count" sig="I" />
|
||||
<newobj type="System.String, mscorlib" name=".ctor" sig="([CII)V" />
|
||||
<ret />
|
||||
</alternateBody>
|
||||
</constructor>
|
||||
<constructor sig="([B)V" modifiers="public">
|
||||
<redirect class="java.lang.StringHelper" name="NewString" type="static" sig="([B)Ljava.lang.String;" />
|
||||
</constructor>
|
||||
|
@ -644,7 +655,7 @@
|
|||
<method name="unbox_byte" sig="(Ljava.lang.Object;)B">
|
||||
<body>
|
||||
<ldarg_0 />
|
||||
<unbox type="System.SByte, mscorlib" />
|
||||
<unbox type="System.Byte, mscorlib" />
|
||||
<ldind_i1 />
|
||||
<ret />
|
||||
</body>
|
||||
|
@ -708,7 +719,7 @@
|
|||
<method name="box_byte" sig="(B)Ljava.lang.Object;">
|
||||
<body>
|
||||
<ldarg_0 />
|
||||
<box type="System.SByte, mscorlib" />
|
||||
<box type="System.Byte, mscorlib" />
|
||||
<ret />
|
||||
</body>
|
||||
</method>
|
||||
|
@ -761,7 +772,7 @@
|
|||
<ret />
|
||||
</body>
|
||||
</method>
|
||||
<method name="box_ubyte" sig="(B)Lcli.System.Byte;">
|
||||
<method name="box_sbyte" sig="(B)Lcli.System.SByte;">
|
||||
<body>
|
||||
<ldarg_0 />
|
||||
<ret />
|
||||
|
@ -785,7 +796,7 @@
|
|||
<ret />
|
||||
</body>
|
||||
</method>
|
||||
<method name="unbox_ubyte" sig="(Lcli.System.Byte;)B">
|
||||
<method name="unbox_sbyte" sig="(Lcli.System.SByte;)B">
|
||||
<body>
|
||||
<ldarg_0 />
|
||||
<ret />
|
||||
|
@ -810,20 +821,6 @@
|
|||
</body>
|
||||
</method>
|
||||
</class>
|
||||
<class name="ikvm.lang.ByteArrayHack">
|
||||
<method name="cast" sig="([B)[Lcli.System.Byte;">
|
||||
<body>
|
||||
<ldarg_0 />
|
||||
<ret />
|
||||
</body>
|
||||
</method>
|
||||
<method name="cast" sig="([Lcli.System.Byte;)[B">
|
||||
<body>
|
||||
<ldarg_0 />
|
||||
<ret />
|
||||
</body>
|
||||
</method>
|
||||
</class>
|
||||
<class name="java.lang.VMClass">
|
||||
<method name="createField" sig="(Ljava.lang.Class;Ljava.lang.Object;)Ljava.lang.reflect.Field;">
|
||||
<body>
|
||||
|
@ -883,11 +880,8 @@
|
|||
<method name="getDirectBufferAddress" sig="(Ljava.lang.Object;)Lcli.System.IntPtr;">
|
||||
<body>
|
||||
<ldarg_1 />
|
||||
<castclass class="java.nio.ByteBuffer" />
|
||||
<call class="java.nio.VMDirectByteBuffer" name="GetDirectBufferAddress" sig="(Ljava.nio.ByteBuffer;)Lcli.System.IntPtr;" />
|
||||
<!-- LAME we need to unbox the return value -->
|
||||
<unbox type="System.IntPtr, mscorlib" />
|
||||
<ldobj type="System.IntPtr, mscorlib" />
|
||||
<castclass class="java.nio.Buffer" />
|
||||
<call class="java.nio.VMDirectByteBuffer" name="GetDirectBufferAddress" sig="(Ljava.nio.Buffer;)Lcli.System.IntPtr;" />
|
||||
<ret />
|
||||
</body>
|
||||
</method>
|
||||
|
@ -909,7 +903,7 @@
|
|||
</body>
|
||||
</method>
|
||||
</class>
|
||||
<class name="java.nio.channels.Channels">
|
||||
<class name="java.nio.channels.VMChannels">
|
||||
<method name="newInputStream" sig="(Lgnu.java.nio.channels.FileChannelImpl;)Ljava.io.FileInputStream;">
|
||||
<body>
|
||||
<ldarg_0 />
|
||||
|
@ -938,7 +932,7 @@
|
|||
<ldarg_0 />
|
||||
<ldfld class="java.nio.Buffer" name="pos" sig="I" />
|
||||
<call type="gnu.classpath.RawData" name="ReadByte" sig="(I)B" />
|
||||
<stloc name="result" type="System.SByte, mscorlib" />
|
||||
<stloc name="result" type="System.Byte, mscorlib" />
|
||||
<ldarg_0 />
|
||||
<ldarg_0 />
|
||||
<ldfld class="java.nio.Buffer" name="pos" sig="I" />
|
||||
|
|
Двоичные данные
classpath/mscorlib.jar
Двоичные данные
classpath/mscorlib.jar
Двоичный файл не отображается.
|
@ -49,7 +49,7 @@ using System.Runtime.CompilerServices;
|
|||
// You can specify all the values or you can default the Revision and Build Numbers
|
||||
// by using the '*' as shown below:
|
||||
|
||||
[assembly: AssemblyVersion("0.10.0.1")]
|
||||
[assembly: AssemblyVersion("0.11.*")]
|
||||
|
||||
//
|
||||
// In order to sign your assembly you must specify a key to use. Refer to the
|
||||
|
|
|
@ -49,7 +49,7 @@ using System.Runtime.CompilerServices;
|
|||
// You can specify all the values or you can default the Revision and Build Numbers
|
||||
// by using the '*' as shown below:
|
||||
|
||||
[assembly: AssemblyVersion("0.10.0.1")]
|
||||
[assembly: AssemblyVersion("0.11.*")]
|
||||
|
||||
//
|
||||
// In order to sign your assembly you must specify a key to use. Refer to the
|
||||
|
|
|
@ -49,7 +49,7 @@ using System.Runtime.CompilerServices;
|
|||
// You can specify all the values or you can default the Revision and Build Numbers
|
||||
// by using the '*' as shown below:
|
||||
|
||||
[assembly: AssemblyVersion("0.10.0.1")]
|
||||
[assembly: AssemblyVersion("0.11.*")]
|
||||
|
||||
//
|
||||
// In order to sign your assembly you must specify a key to use. Refer to the
|
||||
|
|
|
@ -724,9 +724,9 @@ class ClassFileWriter
|
|||
if(constantValue != null)
|
||||
{
|
||||
ushort constantValueIndex;
|
||||
if(constantValue is sbyte)
|
||||
if(constantValue is byte)
|
||||
{
|
||||
constantValueIndex = AddInt((sbyte)constantValue);
|
||||
constantValueIndex = AddInt((sbyte)(byte)constantValue);
|
||||
}
|
||||
else if(constantValue is bool)
|
||||
{
|
||||
|
@ -744,18 +744,10 @@ class ClassFileWriter
|
|||
{
|
||||
constantValueIndex = AddInt((int)constantValue);
|
||||
}
|
||||
else if(constantValue is uint)
|
||||
{
|
||||
constantValueIndex = AddInt((int)(uint)constantValue);
|
||||
}
|
||||
else if(constantValue is long)
|
||||
{
|
||||
constantValueIndex = AddLong((long)constantValue);
|
||||
}
|
||||
else if(constantValue is ulong)
|
||||
{
|
||||
constantValueIndex = AddLong((long)(ulong)constantValue);
|
||||
}
|
||||
else if(constantValue is float)
|
||||
{
|
||||
constantValueIndex = AddFloat((float)constantValue);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2002, 2004 Jeroen Frijters
|
||||
Copyright (C) 2002, 2004, 2005 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
|
||||
|
@ -27,8 +27,6 @@ using System.IO;
|
|||
using System.Text;
|
||||
using System.Collections;
|
||||
using ICSharpCode.SharpZipLib.Zip;
|
||||
using java.lang;
|
||||
using java.lang.reflect;
|
||||
using IKVM.Attributes;
|
||||
using IKVM.Internal;
|
||||
|
||||
|
@ -79,6 +77,7 @@ public class NetExp
|
|||
{
|
||||
assembly = Assembly.LoadWithPartialName(args[0]);
|
||||
}
|
||||
int rc = 0;
|
||||
if(assembly == null)
|
||||
{
|
||||
Console.Error.WriteLine("Error: Assembly \"{0}\" not found", args[0]);
|
||||
|
@ -94,12 +93,13 @@ public class NetExp
|
|||
catch(System.Exception x)
|
||||
{
|
||||
java.lang.Throwable.instancehelper_printStackTrace(IKVM.Runtime.Util.MapException(x));
|
||||
rc = 1;
|
||||
}
|
||||
zipFile.Close();
|
||||
}
|
||||
// FXBUG if we run a static initializer that starts a thread, we would never end,
|
||||
// so we force an exit here
|
||||
Environment.Exit(0);
|
||||
Environment.Exit(rc);
|
||||
}
|
||||
|
||||
private static void WriteClass(string name, ClassFileWriter c)
|
||||
|
@ -114,12 +114,12 @@ public class NetExp
|
|||
{
|
||||
if(t.IsPublic)
|
||||
{
|
||||
Class c;
|
||||
java.lang.Class c;
|
||||
try
|
||||
{
|
||||
c = Class.forName(t.AssemblyQualifiedName, false, null);
|
||||
c = java.lang.Class.forName(t.AssemblyQualifiedName, false, null);
|
||||
}
|
||||
catch(ClassNotFoundException)
|
||||
catch(java.lang.ClassNotFoundException)
|
||||
{
|
||||
// types that IKVM doesn't support don't show up
|
||||
continue;
|
||||
|
@ -139,7 +139,7 @@ public class NetExp
|
|||
Hashtable todo = privateClasses;
|
||||
privateClasses = new Hashtable();
|
||||
keepGoing = false;
|
||||
foreach(Class c in todo.Values)
|
||||
foreach(java.lang.Class c in todo.Values)
|
||||
{
|
||||
if(!done.ContainsKey(c.getName()))
|
||||
{
|
||||
|
@ -151,7 +151,7 @@ public class NetExp
|
|||
} while(keepGoing);
|
||||
}
|
||||
|
||||
private static void ProcessClass(string assemblyName, Class c, Class outer)
|
||||
private static void ProcessClass(string assemblyName, java.lang.Class c, java.lang.Class outer)
|
||||
{
|
||||
string name = c.getName().Replace('.', '/');
|
||||
string super = null;
|
||||
|
@ -159,7 +159,7 @@ public class NetExp
|
|||
{
|
||||
super = c.getSuperclass().getName().Replace('.', '/');
|
||||
// if the base class isn't public, we still need to export it (!)
|
||||
if(!Modifier.isPublic(c.getSuperclass().getModifiers()))
|
||||
if(!java.lang.reflect.Modifier.isPublic(c.getSuperclass().getModifiers()))
|
||||
{
|
||||
privateClasses[c.getSuperclass().getName()] = c.getSuperclass();
|
||||
}
|
||||
|
@ -196,15 +196,15 @@ public class NetExp
|
|||
}
|
||||
innerClassesAttribute.Add(name, outer.getName().Replace('.', '/'), innername, (ushort)c.getModifiers());
|
||||
}
|
||||
Class[] interfaces = c.getInterfaces();
|
||||
java.lang.Class[] interfaces = c.getInterfaces();
|
||||
for(int i = 0; i < interfaces.Length; i++)
|
||||
{
|
||||
if(Modifier.isPublic(interfaces[i].getModifiers()))
|
||||
if(java.lang.reflect.Modifier.isPublic(interfaces[i].getModifiers()))
|
||||
{
|
||||
f.AddInterface(interfaces[i].getName().Replace('.', '/'));
|
||||
}
|
||||
}
|
||||
Class[] innerClasses = c.getDeclaredClasses();
|
||||
java.lang.Class[] innerClasses = c.getDeclaredClasses();
|
||||
for(int i = 0; i < innerClasses.Length; i++)
|
||||
{
|
||||
Modifiers mods = (Modifiers)innerClasses[i].getModifiers();
|
||||
|
@ -220,7 +220,7 @@ public class NetExp
|
|||
ProcessClass(assemblyName, innerClasses[i], c);
|
||||
}
|
||||
}
|
||||
Constructor[] constructors = c.getDeclaredConstructors();
|
||||
java.lang.reflect.Constructor[] constructors = c.getDeclaredConstructors();
|
||||
for(int i = 0; i < constructors.Length; i++)
|
||||
{
|
||||
Modifiers mods = (Modifiers)constructors[i].getModifiers();
|
||||
|
@ -250,7 +250,7 @@ public class NetExp
|
|||
}
|
||||
}
|
||||
}
|
||||
Method[] methods = c.getDeclaredMethods();
|
||||
java.lang.reflect.Method[] methods = c.getDeclaredMethods();
|
||||
for(int i = 0; i < methods.Length; i++)
|
||||
{
|
||||
Modifiers mods = (Modifiers)methods[i].getModifiers();
|
||||
|
@ -269,7 +269,7 @@ public class NetExp
|
|||
}
|
||||
}
|
||||
}
|
||||
Field[] fields = c.getDeclaredFields();
|
||||
java.lang.reflect.Field[] fields = c.getDeclaredFields();
|
||||
for(int i = 0; i < fields.Length; i++)
|
||||
{
|
||||
Modifiers mods = (Modifiers)fields[i].getModifiers();
|
||||
|
@ -340,12 +340,12 @@ public class NetExp
|
|||
WriteClass(name + ".class", f);
|
||||
}
|
||||
|
||||
private static void AddExceptions(ClassFileWriter f, FieldOrMethod m, Class[] exceptions)
|
||||
private static void AddExceptions(ClassFileWriter f, FieldOrMethod m, java.lang.Class[] exceptions)
|
||||
{
|
||||
if(exceptions.Length > 0)
|
||||
{
|
||||
ExceptionsAttribute attrib = new ExceptionsAttribute(f);
|
||||
foreach(Class x in exceptions)
|
||||
foreach(java.lang.Class x in exceptions)
|
||||
{
|
||||
// TODO what happens if one of the exception types is non-public?
|
||||
attrib.Add(x.getName().Replace('.', '/'));
|
||||
|
@ -354,7 +354,7 @@ public class NetExp
|
|||
}
|
||||
}
|
||||
|
||||
private static string MakeSig(Class[] args, Class ret)
|
||||
private static string MakeSig(java.lang.Class[] args, java.lang.Class ret)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.Append('(');
|
||||
|
@ -367,7 +367,7 @@ public class NetExp
|
|||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string ClassToSig(Class c)
|
||||
private static string ClassToSig(java.lang.Class c)
|
||||
{
|
||||
if(c.isPrimitive())
|
||||
{
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<property name="REFERENCE_API_NAME" value="JDK-1.5" />
|
||||
-->
|
||||
<property name="JAPI_HOME" value="c:\japi\japitools" />
|
||||
<property name="IKVM_VERSION" value="0.10.0.0" />
|
||||
<property name="IKVM_VERSION" value="0.11.0.0" />
|
||||
|
||||
<target name="default">
|
||||
<call target="status" />
|
||||
|
|
|
@ -23,12 +23,9 @@
|
|||
*/
|
||||
.assembly JVM
|
||||
{
|
||||
.ver 0:10:0:1
|
||||
.ver 0:11:0:0
|
||||
}
|
||||
.module JVM.DLL
|
||||
.corflags 0x00000002
|
||||
.vtfixup [3] int32 fromunmanaged at VTable
|
||||
.data VTable = int32[3]
|
||||
|
||||
.method public static int32 JNI_CreateJavaVM(void* ppvm, void* ppenv, void* args)
|
||||
{
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
<target name="JVM">
|
||||
<property overwrite="false" name="ilasm_signoption" value="" />
|
||||
<exec program="../tools/asmref.exe" useruntimeengine="true" commandline="mscorlib ../bin/IKVM.Runtime.dll ../bin/IKVM.GNU.Classpath.dll" output="jvm_h.il" />
|
||||
<exec program="ilasm" commandline="/dll ${ilasm_signoption} /out:../bin/JVM.DLL jvm_h.il JVM.il" />
|
||||
<exec program="ilasm" commandline="/dll ${ilasm_signoption} /out:../bin/JVM.DLL jvm_h.il jvm32.il JVM.il" />
|
||||
<!--
|
||||
<exec program="ilasm" commandline="/x64 /dll ${ilasm_signoption} /out:../bin/JVM.DLL jvm_h.il jvm64.il JVM.il" />
|
||||
-->
|
||||
</target>
|
||||
</project>
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
.corflags 0x00000002
|
||||
.vtfixup [3] int32 fromunmanaged at VTable
|
||||
.data VTable = int32[3]
|
|
@ -0,0 +1,2 @@
|
|||
.vtfixup [3] int64 fromunmanaged at VTable
|
||||
.data VTable = int64[3]
|
|
@ -49,7 +49,7 @@ using System.Runtime.CompilerServices;
|
|||
// You can specify all the values or you can default the Revision and Build Numbers
|
||||
// by using the '*' as shown below:
|
||||
|
||||
[assembly: AssemblyVersion("0.10.0.1")]
|
||||
[assembly: AssemblyVersion("0.11.*")]
|
||||
|
||||
//
|
||||
// In order to sign your assembly you must specify a key to use. Refer to the
|
||||
|
|
|
@ -176,7 +176,7 @@ namespace IKVM.Runtime
|
|||
}
|
||||
if(!wrapper.IsAccessibleFrom(context))
|
||||
{
|
||||
throw JavaException.IllegalAccessError("Try to access class " + wrapper.Name + " from class " + clazz);
|
||||
throw JavaException.IllegalAccessError("Try to access class " + wrapper.Name + " from class " + context.Name);
|
||||
}
|
||||
wrapper.Finish();
|
||||
return wrapper;
|
||||
|
@ -262,7 +262,7 @@ namespace IKVM.Runtime
|
|||
public static object DynamicInvokevirtual(object obj, RuntimeTypeHandle type, string clazz, string name, string sig, object[] args)
|
||||
{
|
||||
Profiler.Count("DynamicInvokevirtual");
|
||||
return GetMethodWrapper(ClassLoaderWrapper.GetWrapperFromType(obj.GetType()), type, clazz, name, sig, false).Invoke(obj, args, true);
|
||||
return GetMethodWrapper(ClassLoaderWrapper.GetWrapperFromType(obj.GetType()), type, clazz, name, sig, false).Invoke(obj, args, false);
|
||||
}
|
||||
|
||||
[DebuggerStepThroughAttribute]
|
||||
|
|
|
@ -1116,8 +1116,20 @@ sealed class ClassFile
|
|||
{
|
||||
field = wrapper.GetFieldWrapper(Name, Signature);
|
||||
if(field != null)
|
||||
{
|
||||
bool ok = false;
|
||||
try
|
||||
{
|
||||
field.Link();
|
||||
ok = true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if(!ok)
|
||||
{
|
||||
fieldTypeWrapper = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1569,7 +1581,7 @@ sealed class ClassFile
|
|||
constantValue = (short)classFile.GetConstantPoolConstantInteger(index);
|
||||
break;
|
||||
case "B":
|
||||
constantValue = (sbyte)classFile.GetConstantPoolConstantInteger(index);
|
||||
constantValue = (byte)classFile.GetConstantPoolConstantInteger(index);
|
||||
break;
|
||||
case "C":
|
||||
constantValue = (char)classFile.GetConstantPoolConstantInteger(index);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2002, 2003, 2004 Jeroen Frijters
|
||||
Copyright (C) 2002, 2003, 2004, 2005 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
|
||||
|
@ -504,8 +504,10 @@ class ClassLoaderWrapper
|
|||
// for .NET to handle.
|
||||
private TypeWrapper CreateArrayType(string name, TypeWrapper elementTypeWrapper, int dims)
|
||||
{
|
||||
Debug.Assert(new String('[', dims) + elementTypeWrapper.SigName == name);
|
||||
Debug.Assert(!elementTypeWrapper.IsUnloadable && !elementTypeWrapper.IsVerifierType && !elementTypeWrapper.IsArray);
|
||||
Debug.Assert(dims >= 1);
|
||||
Type elementType = elementTypeWrapper.TypeAsArrayType;
|
||||
Debug.Assert(!elementType.IsArray);
|
||||
TypeWrapper wrapper;
|
||||
lock(types.SyncRoot)
|
||||
{
|
||||
|
@ -809,7 +811,7 @@ class ClassLoaderWrapper
|
|||
Type[] types = new Type[wrappers.Length];
|
||||
for(int i = 0; i < wrappers.Length; i++)
|
||||
{
|
||||
types[i] = wrappers[i].TypeAsParameterType;
|
||||
types[i] = wrappers[i].TypeAsSignatureType;
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
@ -986,11 +988,6 @@ class ClassLoaderWrapper
|
|||
rank++;
|
||||
elem = elem.GetElementType();
|
||||
}
|
||||
// HACK BYTE[]
|
||||
//if(elem == typeof(byte))
|
||||
//{
|
||||
// elem = typeof(sbyte);
|
||||
//}
|
||||
wrapper = GetWrapperFromType(elem);
|
||||
return wrapper.MakeArrayType(rank);
|
||||
}
|
||||
|
|
|
@ -79,13 +79,19 @@ namespace IKVM.Runtime
|
|||
public unsafe sealed class JNI
|
||||
{
|
||||
internal static bool jvmCreated;
|
||||
internal static bool jvmDestroyed;
|
||||
internal const string METHOD_PTR_FIELD_PREFIX = "__<jniptr/";
|
||||
|
||||
internal static bool IsSupportedJniVersion(jint version)
|
||||
{
|
||||
return version == JNIEnv.JNI_VERSION_1_1 || version == JNIEnv.JNI_VERSION_1_2 || version == JNIEnv.JNI_VERSION_1_4;
|
||||
}
|
||||
|
||||
public static int CreateJavaVM(void* ppvm, void* ppenv, void* args)
|
||||
{
|
||||
JavaVMInitArgs* pInitArgs = (JavaVMInitArgs*)args;
|
||||
// we don't support the JDK 1.1 JavaVMInitArgs
|
||||
if(pInitArgs->version != JNIEnv.JNI_VERSION_1_2)
|
||||
if(!IsSupportedJniVersion(pInitArgs->version) || pInitArgs->version == JNIEnv.JNI_VERSION_1_1)
|
||||
{
|
||||
return JNIEnv.JNI_EVERSION;
|
||||
}
|
||||
|
@ -377,43 +383,11 @@ namespace IKVM.Runtime
|
|||
[DllImport("ikvm-native")]
|
||||
internal unsafe static extern void* ikvm_MarshalDelegate(Delegate d);
|
||||
|
||||
private static MethodBase FindCaller()
|
||||
{
|
||||
StackTrace st = new StackTrace();
|
||||
for(int i = 0; i < st.FrameCount; i++)
|
||||
{
|
||||
StackFrame frame = st.GetFrame(i);
|
||||
Type type = frame.GetMethod().DeclaringType;
|
||||
if(type != null && type.Assembly != typeof(JniHelper).Assembly)
|
||||
{
|
||||
// TODO we need a more robust algorithm to find the "caller" (note that in addition to native methods,
|
||||
// System.loadLibrary can also trigger executing native code)
|
||||
ClassLoaderWrapper loader = ClassLoaderWrapper.GetWrapperFromType(type).GetClassLoader();
|
||||
if(loader.GetJavaClassLoader() != null)
|
||||
{
|
||||
return frame.GetMethod();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static ArrayList nativeLibraries = new ArrayList();
|
||||
internal static readonly object JniLock = new object();
|
||||
|
||||
internal unsafe static int LoadLibrary(string filename)
|
||||
internal unsafe static int LoadLibrary(string filename, ClassLoaderWrapper loader)
|
||||
{
|
||||
MethodBase m = FindCaller();
|
||||
ClassLoaderWrapper loader;
|
||||
if(m != null)
|
||||
{
|
||||
loader = ClassLoaderWrapper.GetWrapperFromType(m.DeclaringType).GetClassLoader();
|
||||
}
|
||||
else
|
||||
{
|
||||
loader = ClassLoaderWrapper.GetBootstrapClassLoader();
|
||||
m = MethodBase.GetCurrentMethod();
|
||||
}
|
||||
lock(JniLock)
|
||||
{
|
||||
IntPtr p = ikvm_LoadLibrary(filename);
|
||||
|
@ -444,7 +418,7 @@ namespace IKVM.Runtime
|
|||
ClassLoaderWrapper prevLoader = f.Enter(loader);
|
||||
int version = ikvm_CallOnLoad(onload, JavaVM.pJavaVM, null);
|
||||
f.Leave(prevLoader);
|
||||
if(!JavaVM.IsSupportedJniVersion(version))
|
||||
if(!JNI.IsSupportedJniVersion(version))
|
||||
{
|
||||
throw JavaException.UnsatisfiedLinkError("Unsupported JNI version 0x{0:X} required by {1}", version, filename);
|
||||
}
|
||||
|
@ -922,9 +896,14 @@ namespace IKVM.Runtime
|
|||
|
||||
internal static jint DestroyJavaVM(JavaVM* pJVM)
|
||||
{
|
||||
JVM.Library.jniWaitUntilLastThread();
|
||||
if(JNI.jvmDestroyed)
|
||||
{
|
||||
return JNIEnv.JNI_ERR;
|
||||
}
|
||||
JNI.jvmDestroyed = true;
|
||||
JVM.Library.jniWaitUntilLastThread();
|
||||
return JNIEnv.JNI_OK;
|
||||
}
|
||||
|
||||
internal static jint AttachCurrentThread(JavaVM* pJVM, void **penv, void *args)
|
||||
{
|
||||
|
@ -935,7 +914,7 @@ namespace IKVM.Runtime
|
|||
{
|
||||
if(pAttachArgs != null)
|
||||
{
|
||||
if(pAttachArgs->version != JNIEnv.JNI_VERSION_1_2)
|
||||
if(!JNI.IsSupportedJniVersion(pAttachArgs->version) || pAttachArgs->version == JNIEnv.JNI_VERSION_1_1)
|
||||
{
|
||||
*penv = null;
|
||||
return JNIEnv.JNI_EVERSION;
|
||||
|
@ -950,22 +929,27 @@ namespace IKVM.Runtime
|
|||
// NOTE if we're here, it is *very* likely that the thread was created by native code and not by managed code,
|
||||
// but it's not impossible that the thread started life as a managed thread and if it did the changes to the
|
||||
// thread we're making are somewhat dubious.
|
||||
System.Threading.Thread.CurrentThread.IsBackground = asDaemon;
|
||||
if(pAttachArgs != null)
|
||||
{
|
||||
if(pAttachArgs->name != null && System.Threading.Thread.CurrentThread.Name == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
System.Threading.Thread.CurrentThread.Name = new String(pAttachArgs->name);
|
||||
}
|
||||
catch(InvalidOperationException)
|
||||
{
|
||||
// someone beat us to it...
|
||||
}
|
||||
}
|
||||
// NOTE we're calling UnwrapRef on a null reference, but that's OK because group is a global reference
|
||||
object threadGroup = p->UnwrapRef(pAttachArgs->group);
|
||||
if(threadGroup != null)
|
||||
{
|
||||
// TODO instead of using a thread data slot to communicate the thread group, we should probably use
|
||||
// another mechanism, this is probably a security issue.
|
||||
System.Threading.Thread.SetData(System.Threading.Thread.GetNamedDataSlot("ikvm-thread-group"), threadGroup);
|
||||
JVM.Library.setThreadGroup(threadGroup);
|
||||
}
|
||||
}
|
||||
System.Threading.Thread.CurrentThread.IsBackground = asDaemon;
|
||||
*penv = JNIEnv.CreateJNIEnv();
|
||||
return JNIEnv.JNI_OK;
|
||||
}
|
||||
|
@ -974,7 +958,8 @@ namespace IKVM.Runtime
|
|||
{
|
||||
if(TlsHack.pJNIEnv == null)
|
||||
{
|
||||
return JNIEnv.JNI_EDETACHED;
|
||||
// the JDK allows detaching from an already detached thread
|
||||
return JNIEnv.JNI_OK;
|
||||
}
|
||||
// TODO if we set Thread.IsBackground to false when we attached, now might be a good time to set it back to true.
|
||||
JNIEnv.FreeJNIEnv();
|
||||
|
@ -982,14 +967,9 @@ namespace IKVM.Runtime
|
|||
return JNIEnv.JNI_OK;
|
||||
}
|
||||
|
||||
internal static bool IsSupportedJniVersion(jint version)
|
||||
{
|
||||
return version == JNIEnv.JNI_VERSION_1_1 || version == JNIEnv.JNI_VERSION_1_2 || version == JNIEnv.JNI_VERSION_1_4;
|
||||
}
|
||||
|
||||
internal static jint GetEnv(JavaVM* pJVM, void **penv, jint version)
|
||||
{
|
||||
if(IsSupportedJniVersion(version))
|
||||
if(JNI.IsSupportedJniVersion(version))
|
||||
{
|
||||
JNIEnv* p = TlsHack.pJNIEnv;
|
||||
if(p != null)
|
||||
|
@ -1013,6 +993,8 @@ namespace IKVM.Runtime
|
|||
[StructLayout(LayoutKind.Sequential)]
|
||||
unsafe struct JNIEnv
|
||||
{
|
||||
// NOTE LOCAL_REF_BUCKET_SIZE must be at least 512 to allow all method arguments to fit
|
||||
// in a single slot, because Frame.MakeLocalRef() doesn't support spilling into a new bucket
|
||||
internal const int LOCAL_REF_SHIFT = 10;
|
||||
internal const int LOCAL_REF_BUCKET_SIZE = (1 << LOCAL_REF_SHIFT);
|
||||
internal const int LOCAL_REF_MASK = (LOCAL_REF_BUCKET_SIZE - 1);
|
||||
|
@ -1255,23 +1237,38 @@ namespace IKVM.Runtime
|
|||
return ClassLoaderWrapper.GetSystemClassLoader();
|
||||
}
|
||||
|
||||
internal static jclass FindClass(JNIEnv* pEnv, byte* name)
|
||||
internal static jclass FindClass(JNIEnv* pEnv, byte* pszName)
|
||||
{
|
||||
try
|
||||
{
|
||||
TypeWrapper wrapper = FindNativeMethodClassLoader(pEnv).LoadClassByDottedName(new String((sbyte*)name).Replace('/', '.'));
|
||||
string name = new String((sbyte*)pszName);
|
||||
// don't allow dotted names!
|
||||
if(name.IndexOf('.') >= 0)
|
||||
{
|
||||
SetPendingException(pEnv, JavaException.NoClassDefFoundError(name));
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
// spec doesn't say it, but Sun allows signature format class names (but not for primitives)
|
||||
if(name.StartsWith("L") && name.EndsWith(";"))
|
||||
{
|
||||
name = name.Substring(1, name.Length - 2);
|
||||
}
|
||||
TypeWrapper wrapper = FindNativeMethodClassLoader(pEnv).LoadClassByDottedName(name.Replace('/', '.'));
|
||||
wrapper.Finish();
|
||||
// spec doesn't say it, but Sun runs the static initializer
|
||||
wrapper.RunClassInit();
|
||||
return pEnv->MakeLocalRef(wrapper.ClassObject);
|
||||
}
|
||||
catch(RetargetableJavaException x)
|
||||
{
|
||||
SetPendingException(pEnv, x.ToJava());
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
catch(Exception x)
|
||||
{
|
||||
if(x is RetargetableJavaException)
|
||||
{
|
||||
x = ((RetargetableJavaException)x).ToJava();
|
||||
}
|
||||
if(ClassLoaderWrapper.LoadClassCritical("java.lang.ClassNotFoundException").TypeAsTBD.IsInstanceOfType(x))
|
||||
{
|
||||
x = JavaException.NoClassDefFoundError(x.Message);
|
||||
}
|
||||
SetPendingException(pEnv, x);
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
@ -1415,8 +1412,15 @@ namespace IKVM.Runtime
|
|||
localRefs[pEnv->localRefSlot - 1] = null;
|
||||
if(localRefs[pEnv->localRefSlot] == null)
|
||||
{
|
||||
// we can't use capacity, because the array length must be a power of two
|
||||
localRefs[pEnv->localRefSlot] = new object[LOCAL_REF_BUCKET_SIZE];
|
||||
// we can't use capacity directly, because the array length must be a power of two
|
||||
// and it can't be bigger than LOCAL_REF_BUCKET_SIZE
|
||||
int r = 1;
|
||||
capacity = Math.Min(capacity, LOCAL_REF_BUCKET_SIZE);
|
||||
while(r < capacity)
|
||||
{
|
||||
r *= 2;
|
||||
}
|
||||
localRefs[pEnv->localRefSlot] = new object[r];
|
||||
}
|
||||
return JNI_OK;
|
||||
}
|
||||
|
@ -1600,7 +1604,7 @@ namespace IKVM.Runtime
|
|||
}
|
||||
catch(Exception x)
|
||||
{
|
||||
if(x.GetType() == ClassLoaderWrapper.LoadClassCritical("java.lang.reflect.InvocationTargetException").TypeAsExceptionType)
|
||||
if(ClassLoaderWrapper.LoadClassCritical("java.lang.reflect.InvocationTargetException").TypeAsExceptionType.IsInstanceOfType(x))
|
||||
{
|
||||
x = x.InnerException;
|
||||
}
|
||||
|
@ -1621,6 +1625,8 @@ namespace IKVM.Runtime
|
|||
|
||||
internal static jboolean IsInstanceOf(JNIEnv* pEnv, jobject obj, jclass clazz)
|
||||
{
|
||||
// NOTE if clazz is an interface, this is still the right thing to do
|
||||
// (i.e. if the object implements the interface, we return true)
|
||||
object objClass = IKVM.Runtime.Util.GetClassFromObject(pEnv->UnwrapRef(obj));
|
||||
TypeWrapper w1 = IKVM.NativeCode.java.lang.VMClass.getWrapperFromClass(pEnv->UnwrapRef(clazz));
|
||||
TypeWrapper w2 = IKVM.NativeCode.java.lang.VMClass.getWrapperFromClass(objClass);
|
||||
|
@ -1680,7 +1686,7 @@ namespace IKVM.Runtime
|
|||
object o = InvokeHelper(pEnv, obj, methodID, args, false);
|
||||
if(o != null)
|
||||
{
|
||||
return (jbyte)(sbyte)o;
|
||||
return (jbyte)(byte)o;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1770,7 +1776,7 @@ namespace IKVM.Runtime
|
|||
object o = InvokeHelper(pEnv, obj, methodID, args, true);
|
||||
if(o != null)
|
||||
{
|
||||
return (jbyte)(sbyte)o;
|
||||
return (jbyte)(byte)o;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1851,7 +1857,6 @@ namespace IKVM.Runtime
|
|||
{
|
||||
if(fw.IsStatic == isstatic)
|
||||
{
|
||||
// TODO fw.Link()
|
||||
return fw.Cookie;
|
||||
}
|
||||
}
|
||||
|
@ -1911,7 +1916,7 @@ namespace IKVM.Runtime
|
|||
|
||||
internal static jbyte GetByteField(JNIEnv* pEnv, jobject obj, jfieldID fieldID)
|
||||
{
|
||||
return (jbyte)(sbyte)GetFieldValue(fieldID, pEnv->UnwrapRef(obj));
|
||||
return (jbyte)(byte)GetFieldValue(fieldID, pEnv->UnwrapRef(obj));
|
||||
}
|
||||
|
||||
internal static jchar GetCharField(JNIEnv* pEnv, jobject obj, jfieldID fieldID)
|
||||
|
@ -1956,7 +1961,7 @@ namespace IKVM.Runtime
|
|||
|
||||
internal static void SetByteField(JNIEnv* pEnv, jobject obj, jfieldID fieldID, jbyte val)
|
||||
{
|
||||
SetFieldValue(fieldID, pEnv->UnwrapRef(obj), (sbyte)val);
|
||||
SetFieldValue(fieldID, pEnv->UnwrapRef(obj), (byte)val);
|
||||
}
|
||||
|
||||
internal static void SetCharField(JNIEnv* pEnv, jobject obj, jfieldID fieldID, jchar val)
|
||||
|
@ -2014,7 +2019,7 @@ namespace IKVM.Runtime
|
|||
object o = InvokeHelper(pEnv, IntPtr.Zero, methodID, args, false);
|
||||
if(o != null)
|
||||
{
|
||||
return (jbyte)(sbyte)o;
|
||||
return (jbyte)(byte)o;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -2101,7 +2106,7 @@ namespace IKVM.Runtime
|
|||
|
||||
internal static jbyte GetStaticByteField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID)
|
||||
{
|
||||
return (jbyte)(sbyte)GetFieldValue(fieldID, null);
|
||||
return (jbyte)(byte)GetFieldValue(fieldID, null);
|
||||
}
|
||||
|
||||
internal static jchar GetStaticCharField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID)
|
||||
|
@ -2146,7 +2151,7 @@ namespace IKVM.Runtime
|
|||
|
||||
internal static void SetStaticByteField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID, jbyte val)
|
||||
{
|
||||
SetFieldValue(fieldID, null, (sbyte)val);
|
||||
SetFieldValue(fieldID, null, (byte)val);
|
||||
}
|
||||
|
||||
internal static void SetStaticCharField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID, jchar val)
|
||||
|
@ -2328,7 +2333,7 @@ namespace IKVM.Runtime
|
|||
{
|
||||
try
|
||||
{
|
||||
return pEnv->MakeLocalRef(new sbyte[len]);
|
||||
return pEnv->MakeLocalRef(new byte[len]);
|
||||
}
|
||||
catch(Exception x)
|
||||
{
|
||||
|
@ -2432,7 +2437,7 @@ namespace IKVM.Runtime
|
|||
|
||||
internal static jbyte* GetByteArrayElements(JNIEnv* pEnv, jbyteArray array, jboolean* isCopy)
|
||||
{
|
||||
sbyte[] b = (sbyte[])pEnv->UnwrapRef(array);
|
||||
byte[] b = (byte[])pEnv->UnwrapRef(array);
|
||||
jbyte* p = (jbyte*)(void*)JniMem.Alloc(b.Length * 1);
|
||||
for(int i = 0; i < b.Length; i++)
|
||||
{
|
||||
|
@ -2537,10 +2542,10 @@ namespace IKVM.Runtime
|
|||
{
|
||||
if(mode == 0 || mode == JNI_COMMIT)
|
||||
{
|
||||
sbyte[] b = (sbyte[])pEnv->UnwrapRef(array);
|
||||
byte[] b = (byte[])pEnv->UnwrapRef(array);
|
||||
for(int i = 0; i < b.Length; i++)
|
||||
{
|
||||
b[i] = (sbyte)elems[i];
|
||||
b[i] = (byte)elems[i];
|
||||
}
|
||||
}
|
||||
if(mode == 0 || mode == JNI_ABORT)
|
||||
|
@ -2648,8 +2653,8 @@ namespace IKVM.Runtime
|
|||
{
|
||||
try
|
||||
{
|
||||
sbyte[] b = (sbyte[])pEnv->UnwrapRef(array);
|
||||
sbyte* p = (sbyte*)(void*)buf;
|
||||
byte[] b = (byte[])pEnv->UnwrapRef(array);
|
||||
byte* p = (byte*)(void*)buf;
|
||||
for(int i = 0; i < len; i++)
|
||||
{
|
||||
*p++ = b[start + i];
|
||||
|
@ -2760,8 +2765,8 @@ namespace IKVM.Runtime
|
|||
{
|
||||
try
|
||||
{
|
||||
sbyte[] b = (sbyte[])pEnv->UnwrapRef(array);
|
||||
sbyte* p = (sbyte*)(void*)buf;
|
||||
byte[] b = (byte[])pEnv->UnwrapRef(array);
|
||||
byte* p = (byte*)(void*)buf;
|
||||
for(int i = 0; i < len; i++)
|
||||
{
|
||||
b[start + i] = *p++;
|
||||
|
@ -3023,19 +3028,19 @@ namespace IKVM.Runtime
|
|||
private static int GetPrimitiveArrayElementSize(Array ar)
|
||||
{
|
||||
Type type = ar.GetType().GetElementType();
|
||||
if(type == typeof(sbyte) || type == typeof(bool))
|
||||
if(type == PrimitiveTypeWrapper.BYTE.TypeAsArrayType || type == PrimitiveTypeWrapper.BOOLEAN.TypeAsArrayType)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else if(type == typeof(short) || type == typeof(char))
|
||||
else if(type == PrimitiveTypeWrapper.SHORT.TypeAsArrayType || type == PrimitiveTypeWrapper.CHAR.TypeAsArrayType)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
else if(type == typeof(int) || type == typeof(float))
|
||||
else if(type == PrimitiveTypeWrapper.INT.TypeAsArrayType || type == PrimitiveTypeWrapper.FLOAT.TypeAsArrayType)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
else if(type == typeof(long) || type == typeof(double))
|
||||
else if(type == PrimitiveTypeWrapper.LONG.TypeAsArrayType || type == PrimitiveTypeWrapper.DOUBLE.TypeAsArrayType)
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
|
@ -3049,6 +3054,7 @@ namespace IKVM.Runtime
|
|||
internal static IntPtr GetPrimitiveArrayCritical(JNIEnv* pEnv, IntPtr array, IntPtr isCopy)
|
||||
{
|
||||
Array ar = (Array)pEnv->UnwrapRef(array);
|
||||
// TODO not 64-bit safe (len can overflow)
|
||||
int len = ar.Length * GetPrimitiveArrayElementSize(ar);
|
||||
GCHandle h = GCHandle.Alloc(ar, GCHandleType.Pinned);
|
||||
try
|
||||
|
@ -3078,6 +3084,7 @@ namespace IKVM.Runtime
|
|||
if(mode == 0 || mode == JNI_COMMIT)
|
||||
{
|
||||
Array ar = (Array)pEnv->UnwrapRef(array);
|
||||
// TODO not 64-bit safe (len can overflow)
|
||||
int len = ar.Length * GetPrimitiveArrayElementSize(ar);
|
||||
GCHandle h = GCHandle.Alloc(ar, GCHandleType.Pinned);
|
||||
try
|
||||
|
@ -3165,7 +3172,7 @@ namespace IKVM.Runtime
|
|||
}
|
||||
}
|
||||
|
||||
internal static sbyte ExceptionCheck(JNIEnv* pEnv)
|
||||
internal static jboolean ExceptionCheck(JNIEnv* pEnv)
|
||||
{
|
||||
return pEnv->UnwrapRef(pEnv->pendingException) != null ? JNI_TRUE : JNI_FALSE;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2002, 2003, 2004 Jeroen Frijters
|
||||
Copyright (C) 2002, 2003, 2004, 2005 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
|
||||
|
@ -209,7 +209,7 @@ abstract class MethodWrapper : MemberWrapper
|
|||
{
|
||||
if(ghostMethod == null)
|
||||
{
|
||||
ghostMethod = DeclaringType.TypeAsParameterType.GetMethod(this.Name, this.GetParametersForDefineMethod());
|
||||
ghostMethod = DeclaringType.TypeAsSignatureType.GetMethod(this.Name, this.GetParametersForDefineMethod());
|
||||
if(ghostMethod == null)
|
||||
{
|
||||
throw new InvalidOperationException("Unable to resolve ghost method");
|
||||
|
@ -225,7 +225,7 @@ abstract class MethodWrapper : MemberWrapper
|
|||
|
||||
internal override object Invoke(object obj, object[] args, bool nonVirtual)
|
||||
{
|
||||
object wrapper = Activator.CreateInstance(DeclaringType.TypeAsParameterType);
|
||||
object wrapper = Activator.CreateInstance(DeclaringType.TypeAsSignatureType);
|
||||
DeclaringType.GhostRefField.SetValue(wrapper, obj);
|
||||
|
||||
ResolveGhostMethod();
|
||||
|
@ -245,7 +245,7 @@ abstract class MethodWrapper : MemberWrapper
|
|||
Type[] types = new Type[parameterTypes.Length];
|
||||
for(int i = 0; i < types.Length; i++)
|
||||
{
|
||||
types[i] = parameterTypes[i].TypeAsParameterType;
|
||||
types[i] = parameterTypes[i].TypeAsSignatureType;
|
||||
}
|
||||
method = declaringType.TypeAsBaseType.GetMethod(method.Name, types);
|
||||
}
|
||||
|
@ -383,7 +383,7 @@ abstract class MethodWrapper : MemberWrapper
|
|||
{
|
||||
get
|
||||
{
|
||||
return ReturnType.TypeAsParameterType;
|
||||
return ReturnType.TypeAsSignatureType;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -393,7 +393,7 @@ abstract class MethodWrapper : MemberWrapper
|
|||
Type[] temp = new Type[wrappers.Length];
|
||||
for(int i = 0; i < wrappers.Length; i++)
|
||||
{
|
||||
temp[i] = wrappers[i].TypeAsParameterType;
|
||||
temp[i] = wrappers[i].TypeAsSignatureType;
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
@ -600,7 +600,12 @@ abstract class MethodWrapper : MemberWrapper
|
|||
}
|
||||
}
|
||||
}
|
||||
else if(nonVirtual && !method.IsStatic)
|
||||
else if(nonVirtual &&
|
||||
method.IsVirtual && // if the method isn't virtual, normal reflection will work
|
||||
!method.IsFinal && // if the method is final, normal reflection will work
|
||||
!method.DeclaringType.IsSealed && // if the type is sealed, normal reflection will work
|
||||
!method.IsAbstract) // if the method is abstract, it doesn't make sense, so we'll do a virtual call
|
||||
// (Sun does a virtual call for interface methods and crashes for abstract methods)
|
||||
{
|
||||
Invoker invoker = NonvirtualInvokeHelper.GetInvoker(this);
|
||||
try
|
||||
|
@ -683,6 +688,8 @@ abstract class MethodWrapper : MemberWrapper
|
|||
AssemblyName name = new AssemblyName();
|
||||
name.Name = "NonvirtualInvoker";
|
||||
AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly(name, ClassLoaderWrapper.IsSaveDebugImage ? AssemblyBuilderAccess.RunAndSave : AssemblyBuilderAccess.Run);
|
||||
// the stack walker needs access to this assembly to be able to quickly check for non-virtual invoke frames
|
||||
IKVM.NativeCode.gnu.classpath.VMStackWalker.nonVirtualInvokeAssembly = ab;
|
||||
if(ClassLoaderWrapper.IsSaveDebugImage)
|
||||
{
|
||||
module = ab.DefineDynamicModule("NonvirtualInvoker", "NonvirtualInvoker.dll");
|
||||
|
@ -747,7 +754,10 @@ abstract class MethodWrapper : MemberWrapper
|
|||
}
|
||||
else if(mw.ReturnType.IsGhost)
|
||||
{
|
||||
mw.ReturnType.EmitConvParameterToStackType(ilgen);
|
||||
LocalBuilder local = ilgen.DeclareLocal(mw.ReturnType.TypeAsSignatureType);
|
||||
ilgen.Emit(OpCodes.Stloc, local);
|
||||
ilgen.Emit(OpCodes.Ldloca, local);
|
||||
ilgen.Emit(OpCodes.Ldfld, mw.ReturnType.GhostRefField);
|
||||
}
|
||||
else if(mw.ReturnType.IsPrimitive)
|
||||
{
|
||||
|
@ -780,7 +790,7 @@ abstract class MethodWrapper : MemberWrapper
|
|||
{
|
||||
if(!argTypes[i].IsUnloadable && argTypes[i].IsGhost)
|
||||
{
|
||||
object v = Activator.CreateInstance(argTypes[i].TypeAsParameterType);
|
||||
object v = Activator.CreateInstance(argTypes[i].TypeAsSignatureType);
|
||||
argTypes[i].GhostRefField.SetValue(v, args[i + 1]);
|
||||
args[i + 1] = v;
|
||||
}
|
||||
|
@ -798,7 +808,7 @@ abstract class MethodWrapper : MemberWrapper
|
|||
{
|
||||
this.args = (object[])args.Clone();
|
||||
}
|
||||
object v = Activator.CreateInstance(argTypes[i].TypeAsParameterType);
|
||||
object v = Activator.CreateInstance(argTypes[i].TypeAsSignatureType);
|
||||
argTypes[i].GhostRefField.SetValue(v, args[i]);
|
||||
this.args[i] = v;
|
||||
}
|
||||
|
@ -844,31 +854,11 @@ class SmartMethodWrapper : MethodWrapper
|
|||
{
|
||||
}
|
||||
|
||||
protected void PostEmit(ILGenerator ilgen)
|
||||
{
|
||||
TypeWrapper retType = this.ReturnType;
|
||||
if(!retType.IsUnloadable)
|
||||
{
|
||||
if(retType.IsNonPrimitiveValueType)
|
||||
{
|
||||
retType.EmitBox(ilgen);
|
||||
}
|
||||
else if(retType.IsGhost)
|
||||
{
|
||||
LocalBuilder local = ilgen.DeclareLocal(retType.TypeAsParameterType);
|
||||
ilgen.Emit(OpCodes.Stloc, local);
|
||||
ilgen.Emit(OpCodes.Ldloca, local);
|
||||
ilgen.Emit(OpCodes.Ldfld, retType.GhostRefField);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed override void EmitCall(ILGenerator ilgen)
|
||||
{
|
||||
AssertLinked();
|
||||
PreEmit(ilgen);
|
||||
CallImpl(ilgen);
|
||||
PostEmit(ilgen);
|
||||
}
|
||||
|
||||
protected virtual void CallImpl(ILGenerator ilgen)
|
||||
|
@ -883,13 +873,13 @@ class SmartMethodWrapper : MethodWrapper
|
|||
if(DeclaringType.IsNonPrimitiveValueType)
|
||||
{
|
||||
// callvirt isn't allowed on a value type
|
||||
// TODO we need to check for a null reference
|
||||
CallImpl(ilgen);
|
||||
}
|
||||
else
|
||||
{
|
||||
CallvirtImpl(ilgen);
|
||||
}
|
||||
PostEmit(ilgen);
|
||||
}
|
||||
|
||||
protected virtual void CallvirtImpl(ILGenerator ilgen)
|
||||
|
@ -1281,29 +1271,6 @@ sealed class SimpleFieldWrapper : FieldWrapper
|
|||
}
|
||||
|
||||
protected override void EmitGetImpl(ILGenerator ilgen)
|
||||
{
|
||||
if(FieldTypeWrapper.IsGhost)
|
||||
{
|
||||
FieldInfo fi = GetField();
|
||||
if(fi.IsStatic)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Ldsflda, fi);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(DeclaringType.IsNonPrimitiveValueType)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Unbox, DeclaringType.TypeAsTBD);
|
||||
}
|
||||
ilgen.Emit(OpCodes.Ldflda, fi);
|
||||
}
|
||||
if(IsVolatile)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Volatile);
|
||||
}
|
||||
ilgen.Emit(OpCodes.Ldfld, FieldTypeWrapper.GhostRefField);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!IsStatic && DeclaringType.IsNonPrimitiveValueType)
|
||||
{
|
||||
|
@ -1314,59 +1281,23 @@ sealed class SimpleFieldWrapper : FieldWrapper
|
|||
ilgen.Emit(OpCodes.Volatile);
|
||||
}
|
||||
ilgen.Emit(IsStatic ? OpCodes.Ldsfld : OpCodes.Ldfld, GetField());
|
||||
if(!FieldTypeWrapper.IsUnloadable && FieldTypeWrapper.IsNonPrimitiveValueType)
|
||||
{
|
||||
FieldTypeWrapper.EmitBox(ilgen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void EmitSetImpl(ILGenerator ilgen)
|
||||
{
|
||||
if(FieldTypeWrapper.IsGhost)
|
||||
{
|
||||
FieldInfo fi = GetField();
|
||||
LocalBuilder temp = ilgen.DeclareLocal(FieldTypeWrapper.TypeAsLocalOrStackType);
|
||||
ilgen.Emit(OpCodes.Stloc, temp);
|
||||
if(fi.IsStatic)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Ldsflda, fi);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(DeclaringType.IsNonPrimitiveValueType)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Unbox, DeclaringType.TypeAsTBD);
|
||||
}
|
||||
ilgen.Emit(OpCodes.Ldflda, fi);
|
||||
}
|
||||
ilgen.Emit(OpCodes.Ldloc, temp);
|
||||
if(IsVolatile)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Volatile);
|
||||
}
|
||||
ilgen.Emit(OpCodes.Stfld, FieldTypeWrapper.GhostRefField);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!IsStatic && DeclaringType.IsNonPrimitiveValueType)
|
||||
{
|
||||
FieldInfo fi = GetField();
|
||||
LocalBuilder temp = ilgen.DeclareLocal(FieldTypeWrapper.TypeAsLocalOrStackType);
|
||||
LocalBuilder temp = ilgen.DeclareLocal(fi.FieldType);
|
||||
ilgen.Emit(OpCodes.Stloc, temp);
|
||||
ilgen.Emit(OpCodes.Unbox, DeclaringType.TypeAsTBD);
|
||||
ilgen.Emit(OpCodes.Ldloc, temp);
|
||||
}
|
||||
if(!FieldTypeWrapper.IsUnloadable && FieldTypeWrapper.IsNonPrimitiveValueType)
|
||||
{
|
||||
FieldTypeWrapper.EmitUnbox(ilgen);
|
||||
}
|
||||
if(IsVolatile)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Volatile);
|
||||
}
|
||||
ilgen.Emit(IsStatic ? OpCodes.Stsfld : OpCodes.Stfld, GetField());
|
||||
}
|
||||
ilgen.Emit(IsStatic ? OpCodes.Stsfld : OpCodes.Stfld, fi);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1381,7 +1312,7 @@ sealed class VolatileLongDoubleFieldWrapper : FieldWrapper
|
|||
: base(declaringType, fieldType, name, sig, modifiers, fi)
|
||||
{
|
||||
Debug.Assert(IsVolatile);
|
||||
Debug.Assert(fieldType == PrimitiveTypeWrapper.DOUBLE || fieldType == PrimitiveTypeWrapper.LONG);
|
||||
Debug.Assert(sig == "J" || sig == "D");
|
||||
}
|
||||
|
||||
protected override void EmitGetImpl(ILGenerator ilgen)
|
||||
|
@ -1460,90 +1391,32 @@ sealed class GetterFieldWrapper : FieldWrapper
|
|||
|
||||
protected override void EmitGetImpl(ILGenerator ilgen)
|
||||
{
|
||||
if(IsStatic)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Call, getter);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(DeclaringType.IsNonPrimitiveValueType)
|
||||
if(!IsStatic && DeclaringType.IsNonPrimitiveValueType)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Unbox, DeclaringType.TypeAsTBD);
|
||||
ilgen.Emit(OpCodes.Call, getter);
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE we look at the static-ness of the getter method and not our own,
|
||||
// because for instance fields we can still have a static getter method
|
||||
ilgen.Emit(getter.IsStatic ? OpCodes.Call : OpCodes.Callvirt, getter);
|
||||
}
|
||||
}
|
||||
if(FieldTypeWrapper.IsUnloadable)
|
||||
{
|
||||
// no need to do anything
|
||||
}
|
||||
else if(FieldTypeWrapper.IsGhost)
|
||||
{
|
||||
LocalBuilder temp = ilgen.DeclareLocal(FieldTypeWrapper.TypeAsFieldType);
|
||||
ilgen.Emit(OpCodes.Stloc, temp);
|
||||
ilgen.Emit(OpCodes.Ldloca, temp);
|
||||
ilgen.Emit(OpCodes.Ldfld, FieldTypeWrapper.GhostRefField);
|
||||
}
|
||||
else if(FieldTypeWrapper.IsNonPrimitiveValueType)
|
||||
{
|
||||
FieldTypeWrapper.EmitBox(ilgen);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void EmitSetImpl(ILGenerator ilgen)
|
||||
{
|
||||
FieldInfo fi = GetField();
|
||||
if(FieldTypeWrapper.IsUnloadable)
|
||||
if(!IsStatic && DeclaringType.IsNonPrimitiveValueType)
|
||||
{
|
||||
LocalBuilder temp = ilgen.DeclareLocal(typeof(object));
|
||||
LocalBuilder temp = ilgen.DeclareLocal(fi.FieldType);
|
||||
ilgen.Emit(OpCodes.Stloc, temp);
|
||||
if(DeclaringType.IsNonPrimitiveValueType)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Unbox, DeclaringType.TypeAsTBD);
|
||||
}
|
||||
ilgen.Emit(OpCodes.Ldloc, temp);
|
||||
ilgen.Emit(IsStatic ? OpCodes.Stsfld : OpCodes.Stfld, fi);
|
||||
}
|
||||
else
|
||||
{
|
||||
LocalBuilder temp = ilgen.DeclareLocal(FieldTypeWrapper.TypeAsLocalOrStackType);
|
||||
ilgen.Emit(OpCodes.Stloc, temp);
|
||||
if(FieldTypeWrapper.IsGhost)
|
||||
{
|
||||
if(fi.IsStatic)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Ldsflda, fi);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(DeclaringType.IsNonPrimitiveValueType)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Unbox, DeclaringType.TypeAsTBD);
|
||||
}
|
||||
ilgen.Emit(OpCodes.Ldflda, fi);
|
||||
}
|
||||
ilgen.Emit(OpCodes.Ldloc, temp);
|
||||
ilgen.Emit(OpCodes.Stfld, FieldTypeWrapper.GhostRefField);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(DeclaringType.IsNonPrimitiveValueType)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Unbox, DeclaringType.TypeAsTBD);
|
||||
}
|
||||
ilgen.Emit(OpCodes.Ldloc, temp);
|
||||
if(FieldTypeWrapper.IsNonPrimitiveValueType)
|
||||
{
|
||||
FieldTypeWrapper.EmitUnbox(ilgen);
|
||||
}
|
||||
ilgen.Emit(IsStatic ? OpCodes.Stsfld : OpCodes.Stfld, fi);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE this type is only used for remapped fields, dynamically compiled classes are always finished before we
|
||||
// allow reflection (so we can look at the underlying field in that case)
|
||||
|
@ -1569,6 +1442,8 @@ sealed class ConstantFieldWrapper : FieldWrapper
|
|||
}
|
||||
else if(constant is int ||
|
||||
constant is short ||
|
||||
constant is ushort ||
|
||||
constant is byte ||
|
||||
constant is sbyte ||
|
||||
constant is char ||
|
||||
constant is bool)
|
||||
|
@ -1591,25 +1466,13 @@ sealed class ConstantFieldWrapper : FieldWrapper
|
|||
{
|
||||
ilgen.Emit(OpCodes.Ldc_I8, (long)constant);
|
||||
}
|
||||
else if(constant is byte)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Ldc_I4, ((IConvertible)constant).ToInt32(null));
|
||||
ilgen.Emit(OpCodes.Box, typeof(byte));
|
||||
}
|
||||
else if(constant is ushort)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Ldc_I4, ((IConvertible)constant).ToInt32(null));
|
||||
ilgen.Emit(OpCodes.Box, typeof(ushort));
|
||||
}
|
||||
else if(constant is uint)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Ldc_I4, unchecked((int)((IConvertible)constant).ToUInt32(null)));
|
||||
ilgen.Emit(OpCodes.Box, typeof(uint));
|
||||
}
|
||||
else if(constant is ulong)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Ldc_I8, unchecked((long)(ulong)constant));
|
||||
ilgen.Emit(OpCodes.Box, typeof(ulong));
|
||||
}
|
||||
else if(constant is Enum)
|
||||
{
|
||||
|
@ -1617,12 +1480,10 @@ sealed class ConstantFieldWrapper : FieldWrapper
|
|||
if(val is long)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Ldc_I8, (long)constant);
|
||||
ilgen.Emit(OpCodes.Box, constant.GetType());
|
||||
}
|
||||
else
|
||||
{
|
||||
ilgen.Emit(OpCodes.Ldc_I4, ((IConvertible)constant).ToInt32(null));
|
||||
ilgen.Emit(OpCodes.Box, constant.GetType());
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1635,6 +1496,7 @@ sealed class ConstantFieldWrapper : FieldWrapper
|
|||
{
|
||||
// when constant static final fields are updated, the JIT normally doesn't see that (because the
|
||||
// constant value is inlined), so we emulate that behavior by emitting a Pop
|
||||
// TODO can we have a constant instance field?
|
||||
ilgen.Emit(OpCodes.Pop);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2002, 2003, 2004 Jeroen Frijters
|
||||
Copyright (C) 2002, 2003, 2004, 2005 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
|
||||
|
@ -472,7 +472,7 @@ abstract class TypeWrapper
|
|||
this.name = name;
|
||||
this.baseWrapper = baseWrapper;
|
||||
this.classLoader = classLoader;
|
||||
if(JVM.IsStaticCompiler)
|
||||
if(IsUnloadable || IsVerifierType || JVM.IsStaticCompiler)
|
||||
{
|
||||
this.classObject = null;
|
||||
}
|
||||
|
@ -486,7 +486,7 @@ abstract class TypeWrapper
|
|||
{
|
||||
get
|
||||
{
|
||||
Debug.Assert(!IsUnloadable);
|
||||
Debug.Assert(!IsUnloadable && !IsVerifierType);
|
||||
return classObject;
|
||||
}
|
||||
}
|
||||
|
@ -902,15 +902,7 @@ abstract class TypeWrapper
|
|||
}
|
||||
}
|
||||
|
||||
internal Type TypeAsFieldType
|
||||
{
|
||||
get
|
||||
{
|
||||
return TypeAsParameterType;
|
||||
}
|
||||
}
|
||||
|
||||
internal Type TypeAsParameterType
|
||||
internal Type TypeAsSignatureType
|
||||
{
|
||||
get
|
||||
{
|
||||
|
@ -991,13 +983,7 @@ abstract class TypeWrapper
|
|||
}
|
||||
return Type.GetType(type, true);
|
||||
}
|
||||
Type t = TypeAsTBD;
|
||||
// HACK BYTE[]
|
||||
//if(t == typeof(sbyte))
|
||||
//{
|
||||
// return typeof(byte);
|
||||
//}
|
||||
return t;
|
||||
return TypeAsTBD;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1337,9 +1323,31 @@ abstract class TypeWrapper
|
|||
ilgen.Emit(OpCodes.Box, this.TypeAsTBD);
|
||||
}
|
||||
|
||||
// NOTE sourceType is optional and only used for special types (e.g. interfaces),
|
||||
internal void EmitConvSignatureTypeToStackType(ILGenerator ilgen)
|
||||
{
|
||||
if(IsUnloadable)
|
||||
{
|
||||
}
|
||||
else if(this == PrimitiveTypeWrapper.BYTE)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Conv_I1);
|
||||
}
|
||||
else if(IsNonPrimitiveValueType)
|
||||
{
|
||||
EmitBox(ilgen);
|
||||
}
|
||||
else if(IsGhost)
|
||||
{
|
||||
LocalBuilder local = ilgen.DeclareLocal(TypeAsSignatureType);
|
||||
ilgen.Emit(OpCodes.Stloc, local);
|
||||
ilgen.Emit(OpCodes.Ldloca, local);
|
||||
ilgen.Emit(OpCodes.Ldfld, GhostRefField);
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE sourceType is optional and only used for interfaces,
|
||||
// it is *not* used to automatically downcast
|
||||
internal void EmitConvStackToParameterType(ILGenerator ilgen, TypeWrapper sourceType)
|
||||
internal void EmitConvStackTypeToSignatureType(ILGenerator ilgen, TypeWrapper sourceType)
|
||||
{
|
||||
if(!IsUnloadable)
|
||||
{
|
||||
|
@ -1347,12 +1355,12 @@ abstract class TypeWrapper
|
|||
{
|
||||
LocalBuilder local1 = ilgen.DeclareLocal(TypeAsLocalOrStackType);
|
||||
ilgen.Emit(OpCodes.Stloc, local1);
|
||||
LocalBuilder local2 = ilgen.DeclareLocal(TypeAsParameterType);
|
||||
LocalBuilder local2 = ilgen.DeclareLocal(TypeAsSignatureType);
|
||||
ilgen.Emit(OpCodes.Ldloca, local2);
|
||||
ilgen.Emit(OpCodes.Ldloc, local1);
|
||||
ilgen.Emit(OpCodes.Stfld, GhostRefField);
|
||||
ilgen.Emit(OpCodes.Ldloca, local2);
|
||||
ilgen.Emit(OpCodes.Ldobj, TypeAsParameterType);
|
||||
ilgen.Emit(OpCodes.Ldobj, TypeAsSignatureType);
|
||||
}
|
||||
// because of the way interface merging works, any reference is valid
|
||||
// for any interface reference
|
||||
|
@ -1367,25 +1375,6 @@ abstract class TypeWrapper
|
|||
}
|
||||
}
|
||||
|
||||
internal void EmitConvParameterToStackType(ILGenerator ilgen)
|
||||
{
|
||||
if(IsUnloadable)
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
else if(IsNonPrimitiveValueType)
|
||||
{
|
||||
EmitBox(ilgen);
|
||||
}
|
||||
else if(IsGhost)
|
||||
{
|
||||
LocalBuilder local = ilgen.DeclareLocal(TypeAsParameterType);
|
||||
ilgen.Emit(OpCodes.Stloc, local);
|
||||
ilgen.Emit(OpCodes.Ldloca, local);
|
||||
ilgen.Emit(OpCodes.Ldfld, GhostRefField);
|
||||
}
|
||||
}
|
||||
|
||||
internal virtual void EmitCheckcast(TypeWrapper context, ILGenerator ilgen)
|
||||
{
|
||||
if(IsGhost)
|
||||
|
@ -1599,7 +1588,7 @@ class UnloadableTypeWrapper : TypeWrapper
|
|||
|
||||
class PrimitiveTypeWrapper : TypeWrapper
|
||||
{
|
||||
internal static readonly PrimitiveTypeWrapper BYTE = new PrimitiveTypeWrapper(typeof(sbyte), "B");
|
||||
internal static readonly PrimitiveTypeWrapper BYTE = new PrimitiveTypeWrapper(typeof(byte), "B");
|
||||
internal static readonly PrimitiveTypeWrapper CHAR = new PrimitiveTypeWrapper(typeof(char), "C");
|
||||
internal static readonly PrimitiveTypeWrapper DOUBLE = new PrimitiveTypeWrapper(typeof(double), "D");
|
||||
internal static readonly PrimitiveTypeWrapper FLOAT = new PrimitiveTypeWrapper(typeof(float), "F");
|
||||
|
@ -1675,6 +1664,11 @@ class PrimitiveTypeWrapper : TypeWrapper
|
|||
internal override void Finish(bool forDebugSave)
|
||||
{
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "PrimitiveTypeWrapper[" + sigName + "]";
|
||||
}
|
||||
}
|
||||
|
||||
class BakedTypeCleanupHack
|
||||
|
@ -2278,6 +2272,8 @@ sealed class DynamicTypeWrapper : TypeWrapper
|
|||
{
|
||||
if(wrapper.IsGhost)
|
||||
{
|
||||
// TODO this is low priority, since the current Java class library doesn't define any ghost interfaces
|
||||
// as inner classes
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
// LAMESPEC the CLI spec says interfaces cannot contain nested types (Part.II, 9.6), but that rule isn't enforced
|
||||
|
@ -2473,11 +2469,7 @@ sealed class DynamicTypeWrapper : TypeWrapper
|
|||
{
|
||||
for(int i = 0; i < caller.Length; i++)
|
||||
{
|
||||
if(caller[i].TypeAsParameterType == typeof(sbyte[]) && callee[i].TypeAsParameterType == typeof(byte[]))
|
||||
{
|
||||
// special case for byte array cheating...
|
||||
}
|
||||
else if(!caller[i].IsAssignableTo(callee[i]))
|
||||
if(!caller[i].IsAssignableTo(callee[i]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -2629,7 +2621,7 @@ sealed class DynamicTypeWrapper : TypeWrapper
|
|||
ClassFile.Field fld = classFile.Fields[GetFieldIndex(fw)];
|
||||
string fieldName = fld.Name;
|
||||
TypeWrapper typeWrapper = fw.FieldTypeWrapper;
|
||||
Type type = typeWrapper.TypeAsFieldType;
|
||||
Type type = typeWrapper.TypeAsSignatureType;
|
||||
bool setNameSig = typeWrapper.IsUnloadable || typeWrapper.IsGhostArray;
|
||||
if(setNameSig)
|
||||
{
|
||||
|
@ -2905,15 +2897,15 @@ sealed class DynamicTypeWrapper : TypeWrapper
|
|||
TypeWrapper[] implementers = GetGhostImplementers(wrapper);
|
||||
for(int i = 0; i < implementers.Length; i++)
|
||||
{
|
||||
mb = typeBuilder.DefineMethod("op_Implicit", MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.SpecialName, wrapper.TypeAsParameterType, new Type[] { implementers[i].TypeAsParameterType });
|
||||
mb = typeBuilder.DefineMethod("op_Implicit", MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.SpecialName, wrapper.TypeAsSignatureType, new Type[] { implementers[i].TypeAsSignatureType });
|
||||
AttributeHelper.HideFromJava(mb);
|
||||
ilgen = mb.GetILGenerator();
|
||||
local = ilgen.DeclareLocal(wrapper.TypeAsParameterType);
|
||||
local = ilgen.DeclareLocal(wrapper.TypeAsSignatureType);
|
||||
ilgen.Emit(OpCodes.Ldloca, local);
|
||||
ilgen.Emit(OpCodes.Ldarg_0);
|
||||
ilgen.Emit(OpCodes.Stfld, wrapper.GhostRefField);
|
||||
ilgen.Emit(OpCodes.Ldloca, local);
|
||||
ilgen.Emit(OpCodes.Ldobj, wrapper.TypeAsParameterType);
|
||||
ilgen.Emit(OpCodes.Ldobj, wrapper.TypeAsSignatureType);
|
||||
ilgen.Emit(OpCodes.Ret);
|
||||
}
|
||||
// Implement the "IsInstance" method
|
||||
|
@ -3005,12 +2997,12 @@ sealed class DynamicTypeWrapper : TypeWrapper
|
|||
ilgen.Emit(OpCodes.Castclass, wrapper.TypeAsBaseType);
|
||||
ilgen.Emit(OpCodes.Pop);
|
||||
ilgen.MarkLabel(end);
|
||||
local = ilgen.DeclareLocal(wrapper.TypeAsParameterType);
|
||||
local = ilgen.DeclareLocal(wrapper.TypeAsSignatureType);
|
||||
ilgen.Emit(OpCodes.Ldloca, local);
|
||||
ilgen.Emit(OpCodes.Ldarg_0);
|
||||
ilgen.Emit(OpCodes.Stfld, wrapper.ghostRefField);
|
||||
ilgen.Emit(OpCodes.Ldloca, local);
|
||||
ilgen.Emit(OpCodes.Ldobj, wrapper.TypeAsParameterType);
|
||||
ilgen.Emit(OpCodes.Ldobj, wrapper.TypeAsSignatureType);
|
||||
ilgen.Emit(OpCodes.Ret);
|
||||
// Add "ToObject" methods
|
||||
mb = typeBuilder.DefineMethod("ToObject", MethodAttributes.Public, typeof(object), Type.EmptyTypes);
|
||||
|
@ -3252,15 +3244,15 @@ sealed class DynamicTypeWrapper : TypeWrapper
|
|||
// TODO do this for indirectly implemented interfaces (interfaces implemented by interfaces) as well
|
||||
if(interfaces[i].IsGhost)
|
||||
{
|
||||
MethodBuilder mb = typeBuilder.DefineMethod("op_Implicit", MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.SpecialName, interfaces[i].TypeAsParameterType, new Type[] { wrapper.TypeAsParameterType });
|
||||
MethodBuilder mb = typeBuilder.DefineMethod("op_Implicit", MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.SpecialName, interfaces[i].TypeAsSignatureType, new Type[] { wrapper.TypeAsSignatureType });
|
||||
AttributeHelper.HideFromJava(mb);
|
||||
ILGenerator ilgen = mb.GetILGenerator();
|
||||
LocalBuilder local = ilgen.DeclareLocal(interfaces[i].TypeAsParameterType);
|
||||
LocalBuilder local = ilgen.DeclareLocal(interfaces[i].TypeAsSignatureType);
|
||||
ilgen.Emit(OpCodes.Ldloca, local);
|
||||
ilgen.Emit(OpCodes.Ldarg_0);
|
||||
ilgen.Emit(OpCodes.Stfld, interfaces[i].GhostRefField);
|
||||
ilgen.Emit(OpCodes.Ldloca, local);
|
||||
ilgen.Emit(OpCodes.Ldobj, interfaces[i].TypeAsParameterType);
|
||||
ilgen.Emit(OpCodes.Ldobj, interfaces[i].TypeAsSignatureType);
|
||||
ilgen.Emit(OpCodes.Ret);
|
||||
}
|
||||
interfaces[i].ImplementInterfaceMethodStubs(typeBuilder, wrapper, doneSet);
|
||||
|
@ -3321,13 +3313,13 @@ sealed class DynamicTypeWrapper : TypeWrapper
|
|||
if(f.ConstantValue != null)
|
||||
{
|
||||
FieldAttributes attribs = FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal;
|
||||
FieldBuilder fb = tbFields.DefineField(f.Name, typeWrapper.TypeAsFieldType, attribs);
|
||||
FieldBuilder fb = tbFields.DefineField(f.Name, typeWrapper.TypeAsSignatureType, attribs);
|
||||
fb.SetConstant(f.ConstantValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
FieldAttributes attribs = FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.InitOnly;
|
||||
FieldBuilder fb = tbFields.DefineField(f.Name, typeWrapper.TypeAsFieldType, attribs);
|
||||
FieldBuilder fb = tbFields.DefineField(f.Name, typeWrapper.TypeAsSignatureType, attribs);
|
||||
if(ilgenClinit == null)
|
||||
{
|
||||
ilgenClinit = tbFields.DefineTypeInitializer().GetILGenerator();
|
||||
|
@ -3406,14 +3398,14 @@ sealed class DynamicTypeWrapper : TypeWrapper
|
|||
Type[] argTypes = new Type[args.Length + instance + 1];
|
||||
if(instance != 0)
|
||||
{
|
||||
argTypes[0] = wrapper.TypeAsParameterType;
|
||||
argTypes[0] = wrapper.TypeAsSignatureType;
|
||||
}
|
||||
for(int i = 0; i < args.Length; i++)
|
||||
{
|
||||
argTypes[i + instance] = args[i].TypeAsParameterType;
|
||||
argTypes[i + instance] = args[i].TypeAsSignatureType;
|
||||
}
|
||||
argTypes[argTypes.Length - 1] = typeof(RuntimeMethodHandle);
|
||||
MethodBuilder mb = tb.DefineMethod("method", MethodAttributes.Public | MethodAttributes.Static, mw.ReturnType.TypeAsParameterType, argTypes);
|
||||
MethodBuilder mb = tb.DefineMethod("method", MethodAttributes.Public | MethodAttributes.Static, mw.ReturnType.TypeAsSignatureType, argTypes);
|
||||
JniBuilder.Generate(mb.GetILGenerator(), wrapper, mw, tb, classFile, m, args, true);
|
||||
for(int i = 0; i < argTypes.Length - 1; i++)
|
||||
{
|
||||
|
@ -3507,7 +3499,7 @@ sealed class DynamicTypeWrapper : TypeWrapper
|
|||
ilGenerator.Emit(OpCodes.Stloc, jnienv);
|
||||
Label tryBlock = ilGenerator.BeginExceptionBlock();
|
||||
TypeWrapper retTypeWrapper = mw.ReturnType;
|
||||
if(!retTypeWrapper.IsPrimitive)
|
||||
if(!retTypeWrapper.IsUnloadable && !retTypeWrapper.IsPrimitive)
|
||||
{
|
||||
// this one is for use after we return from "calli"
|
||||
ilGenerator.Emit(OpCodes.Ldloca, localRefStruct);
|
||||
|
@ -3518,7 +3510,7 @@ sealed class DynamicTypeWrapper : TypeWrapper
|
|||
modargs[1] = typeof(IntPtr);
|
||||
for(int i = 0; i < args.Length; i++)
|
||||
{
|
||||
modargs[i + 2] = args[i].TypeAsParameterType;
|
||||
modargs[i + 2] = args[i].TypeAsSignatureType;
|
||||
}
|
||||
int add = 0;
|
||||
if(!m.IsStatic)
|
||||
|
@ -3548,11 +3540,20 @@ sealed class DynamicTypeWrapper : TypeWrapper
|
|||
if(!args[j].IsPrimitive)
|
||||
{
|
||||
ilGenerator.Emit(OpCodes.Ldloca, localRefStruct);
|
||||
ilGenerator.Emit(OpCodes.Ldarg_S, (byte)(j + add));
|
||||
if(args[j].IsNonPrimitiveValueType)
|
||||
{
|
||||
ilGenerator.Emit(OpCodes.Ldarg_S, (byte)(j + add));
|
||||
args[j].EmitBox(ilGenerator);
|
||||
}
|
||||
else if(args[j].IsGhost)
|
||||
{
|
||||
ilGenerator.Emit(OpCodes.Ldarga_S, (byte)(j + add));
|
||||
ilGenerator.Emit(OpCodes.Ldfld, args[j].GhostRefField);
|
||||
}
|
||||
else
|
||||
{
|
||||
ilGenerator.Emit(OpCodes.Ldarg_S, (byte)(j + add));
|
||||
}
|
||||
ilGenerator.Emit(OpCodes.Call, makeLocalRef);
|
||||
modargs[j + 2] = typeof(IntPtr);
|
||||
}
|
||||
|
@ -3562,7 +3563,7 @@ sealed class DynamicTypeWrapper : TypeWrapper
|
|||
}
|
||||
}
|
||||
ilGenerator.Emit(OpCodes.Ldsfld, methodPtr);
|
||||
ilGenerator.EmitCalli(OpCodes.Calli, System.Runtime.InteropServices.CallingConvention.StdCall, (retTypeWrapper.IsPrimitive) ? retTypeWrapper.TypeAsParameterType : typeof(IntPtr), modargs);
|
||||
ilGenerator.EmitCalli(OpCodes.Calli, System.Runtime.InteropServices.CallingConvention.StdCall, (retTypeWrapper.IsPrimitive) ? retTypeWrapper.TypeAsSignatureType : typeof(IntPtr), modargs);
|
||||
LocalBuilder retValue = null;
|
||||
if(retTypeWrapper != PrimitiveTypeWrapper.VOID)
|
||||
{
|
||||
|
@ -3573,12 +3574,22 @@ sealed class DynamicTypeWrapper : TypeWrapper
|
|||
{
|
||||
retTypeWrapper.EmitUnbox(ilGenerator);
|
||||
}
|
||||
else if(!retTypeWrapper.IsGhost)
|
||||
else if(retTypeWrapper.IsGhost)
|
||||
{
|
||||
LocalBuilder ghost = ilGenerator.DeclareLocal(retTypeWrapper.TypeAsSignatureType);
|
||||
LocalBuilder obj = ilGenerator.DeclareLocal(typeof(object));
|
||||
ilGenerator.Emit(OpCodes.Stloc, obj);
|
||||
ilGenerator.Emit(OpCodes.Ldloca, ghost);
|
||||
ilGenerator.Emit(OpCodes.Ldloc, obj);
|
||||
ilGenerator.Emit(OpCodes.Stfld, retTypeWrapper.GhostRefField);
|
||||
ilGenerator.Emit(OpCodes.Ldloc, ghost);
|
||||
}
|
||||
else
|
||||
{
|
||||
ilGenerator.Emit(OpCodes.Castclass, retTypeWrapper.TypeAsTBD);
|
||||
}
|
||||
}
|
||||
retValue = ilGenerator.DeclareLocal(retTypeWrapper.TypeAsParameterType);
|
||||
retValue = ilGenerator.DeclareLocal(retTypeWrapper.TypeAsSignatureType);
|
||||
ilGenerator.Emit(OpCodes.Stloc, retValue);
|
||||
}
|
||||
ilGenerator.BeginCatchBlock(typeof(object));
|
||||
|
@ -5069,7 +5080,7 @@ sealed class DotNetTypeWrapper : TypeWrapper
|
|||
{
|
||||
modifiers |= Modifiers.Final;
|
||||
}
|
||||
if(type.IsAbstract)
|
||||
else if(type.IsAbstract) // we can't be abstract if we're final
|
||||
{
|
||||
modifiers |= Modifiers.Abstract;
|
||||
}
|
||||
|
@ -5374,8 +5385,9 @@ sealed class DotNetTypeWrapper : TypeWrapper
|
|||
|
||||
internal override void EmitCall(ILGenerator ilgen)
|
||||
{
|
||||
// NOTE we don't support custom boxing rules for enums
|
||||
ilgen.Emit(OpCodes.Box, ((DotNetTypeWrapper)DeclaringType).type);
|
||||
// We don't actually need to do anything here!
|
||||
// The compiler will insert a boxing operation after calling us and that will
|
||||
// result in our argument being boxed (since that's still sitting on the stack).
|
||||
}
|
||||
|
||||
internal override object Invoke(object obj, object[] args, bool nonVirtual)
|
||||
|
@ -5432,13 +5444,13 @@ sealed class DotNetTypeWrapper : TypeWrapper
|
|||
}
|
||||
|
||||
// this method takes a boxed Enum and returns its value as a boxed primitive
|
||||
// of the subset of Java primitives (i.e. sbyte, short, int, long)
|
||||
// of the subset of Java primitives (i.e. byte, short, int, long)
|
||||
internal static object GetEnumPrimitiveValue(object obj)
|
||||
{
|
||||
Type underlyingType = Enum.GetUnderlyingType(obj.GetType());
|
||||
if(underlyingType == typeof(sbyte) || underlyingType == typeof(byte))
|
||||
{
|
||||
return unchecked((sbyte)((IConvertible)obj).ToInt32(null));
|
||||
return unchecked((byte)((IConvertible)obj).ToInt32(null));
|
||||
}
|
||||
else if(underlyingType == typeof(short) || underlyingType == typeof(ushort))
|
||||
{
|
||||
|
@ -5512,9 +5524,9 @@ sealed class DotNetTypeWrapper : TypeWrapper
|
|||
if(type.IsEnum)
|
||||
{
|
||||
Type underlyingType = Enum.GetUnderlyingType(type);
|
||||
if(underlyingType == typeof(byte))
|
||||
if(underlyingType == typeof(sbyte))
|
||||
{
|
||||
underlyingType = typeof(sbyte);
|
||||
underlyingType = typeof(byte);
|
||||
}
|
||||
else if(underlyingType == typeof(ushort))
|
||||
{
|
||||
|
@ -5631,6 +5643,7 @@ sealed class DotNetTypeWrapper : TypeWrapper
|
|||
// (otherwise the type appears abstract while it isn't)
|
||||
if(!type.IsAbstract)
|
||||
{
|
||||
Hashtable clash = null;
|
||||
Type[] interfaces = type.GetInterfaces();
|
||||
for(int i = 0; i < interfaces.Length; i++)
|
||||
{
|
||||
|
@ -5653,7 +5666,17 @@ sealed class DotNetTypeWrapper : TypeWrapper
|
|||
continue;
|
||||
}
|
||||
}
|
||||
// TODO handle name/signature clash
|
||||
if(clash == null)
|
||||
{
|
||||
clash = new Hashtable();
|
||||
foreach(MethodWrapper mw in methodsList)
|
||||
{
|
||||
clash.Add(mw.Name + mw.Signature, null);
|
||||
}
|
||||
}
|
||||
if(!clash.ContainsKey(name + sig))
|
||||
{
|
||||
clash.Add(name + sig, null);
|
||||
methodsList.Add(CreateMethodWrapper(name, sig, map.InterfaceMethods[j], true));
|
||||
}
|
||||
}
|
||||
|
@ -5661,6 +5684,7 @@ sealed class DotNetTypeWrapper : TypeWrapper
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// for non-final remapped types, we need to add all the virtual methods in our alter ego (which
|
||||
// appears as our base class) and make them final (to prevent Java code from overriding these
|
||||
|
|
|
@ -418,7 +418,7 @@ namespace IKVM.Attributes
|
|||
this.val = val;
|
||||
}
|
||||
|
||||
public ConstantValueAttribute(sbyte val)
|
||||
public ConstantValueAttribute(byte val)
|
||||
{
|
||||
this.val = val;
|
||||
}
|
||||
|
|
|
@ -164,6 +164,13 @@ namespace IKVM.NativeCode.java
|
|||
throw JavaException.IllegalArgumentException("primitive wrapper null");
|
||||
}
|
||||
argsCopy[i] = JVM.Library.unbox(args[i]);
|
||||
// NOTE we depend on the fact that the .NET reflection parameter type
|
||||
// widening rules are the same as in Java, but to have this work for byte
|
||||
// we need to convert byte to sbyte.
|
||||
if(argsCopy[i] is byte && argWrappers[i] != PrimitiveTypeWrapper.BYTE)
|
||||
{
|
||||
argsCopy[i] = (sbyte)(byte)argsCopy[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -221,16 +228,6 @@ namespace IKVM.NativeCode.java
|
|||
return VMClass.getWrapperFromClass(a).IsInSamePackageAs(VMClass.getWrapperFromClass(b));
|
||||
}
|
||||
|
||||
public static object getClassFromFrame(NetSystem.Diagnostics.StackFrame frame)
|
||||
{
|
||||
Type type = frame.GetMethod().DeclaringType;
|
||||
if(type == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return VMClass.getClassFromType(type);
|
||||
}
|
||||
|
||||
public static object GetValue(object fieldCookie, object o)
|
||||
{
|
||||
Profiler.Enter("Field.GetValue");
|
||||
|
@ -272,6 +269,13 @@ namespace IKVM.NativeCode.java
|
|||
if(wrapper.FieldTypeWrapper.IsPrimitive)
|
||||
{
|
||||
v = JVM.Library.unbox(v);
|
||||
// NOTE we depend on the fact that the .NET reflection parameter type
|
||||
// widening rules are the same as in Java, but to have this work for byte
|
||||
// we need to convert byte to sbyte.
|
||||
if(v is byte && wrapper.FieldTypeWrapper != PrimitiveTypeWrapper.BYTE)
|
||||
{
|
||||
v = (sbyte)(byte)v;
|
||||
}
|
||||
}
|
||||
// if the field is an interface field, we must explicitly run <clinit>,
|
||||
// because .NET reflection doesn't
|
||||
|
@ -291,9 +295,9 @@ namespace IKVM.NativeCode.java
|
|||
|
||||
public class VMRuntime
|
||||
{
|
||||
public static int nativeLoad(string filename)
|
||||
public static int nativeLoad(string filename, object classLoader)
|
||||
{
|
||||
return IKVM.Runtime.JniHelper.LoadLibrary(filename);
|
||||
return IKVM.Runtime.JniHelper.LoadLibrary(filename, ClassLoaderWrapper.GetClassLoaderWrapper(classLoader));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -541,50 +545,6 @@ namespace IKVM.NativeCode.java
|
|||
}
|
||||
}
|
||||
|
||||
public class VMSecurityManager
|
||||
{
|
||||
public static object getClassContext()
|
||||
{
|
||||
ArrayList ar = new ArrayList();
|
||||
NetSystem.Diagnostics.StackTrace st = new NetSystem.Diagnostics.StackTrace();
|
||||
for(int i = 0; i < st.FrameCount; i++)
|
||||
{
|
||||
NetSystem.Diagnostics.StackFrame frame = st.GetFrame(i);
|
||||
// HACK very insecure
|
||||
// TODO handle reflection scenario
|
||||
if(frame.GetMethod().Name != "getClassContext")
|
||||
{
|
||||
Type type = frame.GetMethod().DeclaringType;
|
||||
if(type != null)
|
||||
{
|
||||
ar.Add(VMClass.getClassFromType(type));
|
||||
}
|
||||
}
|
||||
}
|
||||
return ar.ToArray(CoreClasses.java.lang.Class.Wrapper.TypeAsArrayType);
|
||||
}
|
||||
|
||||
public static object currentClassLoader()
|
||||
{
|
||||
// TODO handle PrivilegedAction
|
||||
NetSystem.Diagnostics.StackTrace st = new NetSystem.Diagnostics.StackTrace();
|
||||
for(int i = 0; i < st.FrameCount; i++)
|
||||
{
|
||||
NetSystem.Diagnostics.StackFrame frame = st.GetFrame(i);
|
||||
Type type = frame.GetMethod().DeclaringType;
|
||||
if(type != null)
|
||||
{
|
||||
TypeWrapper wrapper = ClassLoaderWrapper.GetWrapperFromTypeFast(type);
|
||||
if(wrapper != null && wrapper.GetClassLoader().GetJavaClassLoader() != null)
|
||||
{
|
||||
return wrapper.GetClassLoader().GetJavaClassLoader();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public class VMSystem
|
||||
{
|
||||
public static void arraycopy(object src, int srcStart, object dest, int destStart, int len)
|
||||
|
@ -723,6 +683,22 @@ namespace IKVM.NativeCode.java
|
|||
Profiler.Leave("ClassLoader.defineClass");
|
||||
}
|
||||
}
|
||||
|
||||
public static string getPackageName(Type type)
|
||||
{
|
||||
// TODO consider optimizing this (by getting the type name without constructing the TypeWrapper)
|
||||
string name = ClassLoaderWrapper.GetWrapperFromType(type).Name;
|
||||
// if we process mscorlib and we encounter a primitive, the name will be null
|
||||
if(name != null)
|
||||
{
|
||||
int dot = name.LastIndexOf('.');
|
||||
if(dot > 0)
|
||||
{
|
||||
return name.Substring(0, dot);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public class VMClass
|
||||
|
@ -1162,7 +1138,7 @@ namespace IKVM.NativeCode.java
|
|||
GetFieldWrapperFromField(field).SetValue(obj, val);
|
||||
}
|
||||
|
||||
public static void setByteNative(object field, object obj, sbyte val)
|
||||
public static void setByteNative(object field, object obj, byte val)
|
||||
{
|
||||
GetFieldWrapperFromField(field).SetValue(obj, val);
|
||||
}
|
||||
|
@ -1185,7 +1161,21 @@ namespace IKVM.NativeCode.java
|
|||
// TODO calling currentClassLoader in SecurityManager results in null being returned, so we use our own
|
||||
// version for now, don't know what the security implications of this are
|
||||
// SECURITY
|
||||
return NativeCode.java.lang.VMSecurityManager.currentClassLoader();
|
||||
NetSystem.Diagnostics.StackTrace st = new NetSystem.Diagnostics.StackTrace();
|
||||
for(int i = 0; i < st.FrameCount; i++)
|
||||
{
|
||||
NetSystem.Diagnostics.StackFrame frame = st.GetFrame(i);
|
||||
Type type = frame.GetMethod().DeclaringType;
|
||||
if(type != null)
|
||||
{
|
||||
TypeWrapper wrapper = ClassLoaderWrapper.GetWrapperFromTypeFast(type);
|
||||
if(wrapper != null && wrapper.GetClassLoader().GetJavaClassLoader() != null)
|
||||
{
|
||||
return wrapper.GetClassLoader().GetJavaClassLoader();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static object allocateObject(object ois, object clazz, object constructor_clazz, object constructor)
|
||||
|
@ -1223,9 +1213,9 @@ namespace IKVM.NativeCode.java
|
|||
{
|
||||
public class InetAddress
|
||||
{
|
||||
public static sbyte[] lookupInaddrAny()
|
||||
public static byte[] lookupInaddrAny()
|
||||
{
|
||||
return new sbyte[] { 0, 0, 0, 0 };
|
||||
return new byte[] { 0, 0, 0, 0 };
|
||||
}
|
||||
|
||||
public static string getLocalHostname()
|
||||
|
@ -1234,23 +1224,17 @@ namespace IKVM.NativeCode.java
|
|||
return NetSystem.Net.Dns.GetHostName();
|
||||
}
|
||||
|
||||
public static sbyte[][] getHostByName(string name)
|
||||
public static byte[][] getHostByName(string name)
|
||||
{
|
||||
// TODO error handling
|
||||
try
|
||||
{
|
||||
NetSystem.Net.IPHostEntry he = NetSystem.Net.Dns.GetHostByName(name);
|
||||
NetSystem.Net.IPAddress[] addresses = he.AddressList;
|
||||
sbyte[][] list = new sbyte[addresses.Length][];
|
||||
byte[][] list = new byte[addresses.Length][];
|
||||
for(int i = 0; i < addresses.Length; i++)
|
||||
{
|
||||
byte[] address = addresses[i].GetAddressBytes();
|
||||
sbyte[] sb = new sbyte[address.Length];
|
||||
for(int j = 0; j < sb.Length; j++)
|
||||
{
|
||||
sb[j] = (sbyte)address[j];
|
||||
}
|
||||
list[i] = sb;
|
||||
list[i] = addresses[i].GetAddressBytes();
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
@ -1392,6 +1376,31 @@ namespace IKVM.NativeCode.gnu.classpath
|
|||
return typeof(VMSystemProperties).Assembly.GetName().Version.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public class VMStackWalker
|
||||
{
|
||||
internal static volatile Assembly nonVirtualInvokeAssembly;
|
||||
|
||||
public static object getClassFromType(Type type)
|
||||
{
|
||||
return IKVM.NativeCode.java.lang.VMClass.getClassFromType(type);
|
||||
}
|
||||
|
||||
public static object getClassLoaderFromType(Type type)
|
||||
{
|
||||
return IKVM.NativeCode.java.lang.VMClass.getClassLoaderFromType(type);
|
||||
}
|
||||
|
||||
public static Type getJNIEnvType()
|
||||
{
|
||||
return typeof(IKVM.Runtime.JNIEnv);
|
||||
}
|
||||
|
||||
public static Assembly getNonVirtualInvokeAssembly()
|
||||
{
|
||||
return nonVirtualInvokeAssembly;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace gnu.classpath
|
||||
|
@ -1401,11 +1410,11 @@ namespace gnu.classpath
|
|||
public unsafe sealed class RawData
|
||||
{
|
||||
[HideFromJava]
|
||||
private sbyte* pb;
|
||||
private byte* pb;
|
||||
|
||||
public RawData(IntPtr p)
|
||||
{
|
||||
this.pb = (sbyte*)p;
|
||||
this.pb = (byte*)p;
|
||||
}
|
||||
|
||||
public IntPtr p()
|
||||
|
@ -1417,13 +1426,13 @@ namespace gnu.classpath
|
|||
// security attribute isn't really needed, but to be extra safe we add the explicit link
|
||||
// demand to these dangerous methods.
|
||||
[SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true)]
|
||||
public sbyte ReadByte(int index)
|
||||
public byte ReadByte(int index)
|
||||
{
|
||||
return pb[index];
|
||||
}
|
||||
|
||||
[SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true)]
|
||||
public void WriteByte(int index, sbyte b)
|
||||
public void WriteByte(int index, byte b)
|
||||
{
|
||||
pb[index] = b;
|
||||
}
|
||||
|
@ -1467,6 +1476,7 @@ namespace ikvm.@internal
|
|||
|
||||
void jniWaitUntilLastThread();
|
||||
void jniDetach();
|
||||
void setThreadGroup(object group);
|
||||
|
||||
object newConstructor(object clazz, object wrapper);
|
||||
object newMethod(object clazz, object wrapper);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2002, 2003, 2004 Jeroen Frijters
|
||||
Copyright (C) 2002, 2003, 2004, 2005 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
|
||||
|
@ -175,8 +175,9 @@ class Compiler
|
|||
{
|
||||
tw = args[arg - 1];
|
||||
}
|
||||
if(v.type != VerifierTypeWrapper.UninitializedThis &&
|
||||
(v.type != tw || tw.TypeAsLocalOrStackType != tw.TypeAsParameterType))
|
||||
if(!tw.IsUnloadable &&
|
||||
v.type != VerifierTypeWrapper.UninitializedThis &&
|
||||
(v.type != tw || tw.TypeAsLocalOrStackType != tw.TypeAsSignatureType))
|
||||
{
|
||||
v.builder = ilGenerator.DeclareLocal(v.type.TypeAsLocalOrStackType);
|
||||
if(JVM.Debug && v.name != null)
|
||||
|
@ -185,7 +186,7 @@ class Compiler
|
|||
}
|
||||
v.isArg = false;
|
||||
ilGenerator.Emit(OpCodes.Ldarg_S, (byte)arg);
|
||||
v.type.EmitConvParameterToStackType(ilGenerator);
|
||||
tw.EmitConvSignatureTypeToStackType(ilGenerator);
|
||||
ilGenerator.Emit(OpCodes.Stloc, v.builder);
|
||||
}
|
||||
}
|
||||
|
@ -1421,6 +1422,7 @@ class Compiler
|
|||
// we must emit code to cast the stack value to the interface type
|
||||
CastInterfaceArgs(method, cpi.GetArgTypes(), i, false, false);
|
||||
method.EmitCall(ilGenerator);
|
||||
method.ReturnType.EmitConvSignatureTypeToStackType(ilGenerator);
|
||||
break;
|
||||
}
|
||||
case NormalizedByteCode.__invokevirtual:
|
||||
|
@ -1614,6 +1616,7 @@ class Compiler
|
|||
{
|
||||
method.EmitCallvirt(ilGenerator);
|
||||
}
|
||||
method.ReturnType.EmitConvSignatureTypeToStackType(ilGenerator);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1631,12 +1634,12 @@ class Compiler
|
|||
if(instr.NormalizedOpCode != NormalizedByteCode.__return)
|
||||
{
|
||||
TypeWrapper retTypeWrapper = mw.ReturnType;
|
||||
retTypeWrapper.EmitConvStackToParameterType(ilGenerator, ma.GetRawStackTypeWrapper(i, 0));
|
||||
retTypeWrapper.EmitConvStackTypeToSignatureType(ilGenerator, ma.GetRawStackTypeWrapper(i, 0));
|
||||
if(ma.GetRawStackTypeWrapper(i, 0).IsUnloadable)
|
||||
{
|
||||
ilGenerator.Emit(OpCodes.Castclass, retTypeWrapper.TypeAsParameterType);
|
||||
ilGenerator.Emit(OpCodes.Castclass, retTypeWrapper.TypeAsSignatureType);
|
||||
}
|
||||
local = ilGenerator.DeclareLocal(retTypeWrapper.TypeAsParameterType);
|
||||
local = ilGenerator.DeclareLocal(retTypeWrapper.TypeAsSignatureType);
|
||||
ilGenerator.Emit(OpCodes.Stloc, local);
|
||||
}
|
||||
Label label = ilGenerator.DefineLabel();
|
||||
|
@ -1660,14 +1663,14 @@ class Compiler
|
|||
else
|
||||
{
|
||||
TypeWrapper retTypeWrapper = mw.ReturnType;
|
||||
retTypeWrapper.EmitConvStackToParameterType(ilGenerator, ma.GetRawStackTypeWrapper(i, 0));
|
||||
retTypeWrapper.EmitConvStackTypeToSignatureType(ilGenerator, ma.GetRawStackTypeWrapper(i, 0));
|
||||
if(ma.GetRawStackTypeWrapper(i, 0).IsUnloadable)
|
||||
{
|
||||
ilGenerator.Emit(OpCodes.Castclass, retTypeWrapper.TypeAsParameterType);
|
||||
ilGenerator.Emit(OpCodes.Castclass, retTypeWrapper.TypeAsSignatureType);
|
||||
}
|
||||
if(stackHeight != 1)
|
||||
{
|
||||
LocalBuilder local = ilGenerator.DeclareLocal(retTypeWrapper.TypeAsParameterType);
|
||||
LocalBuilder local = ilGenerator.DeclareLocal(retTypeWrapper.TypeAsSignatureType);
|
||||
ilGenerator.Emit(OpCodes.Stloc, local);
|
||||
ilGenerator.Emit(OpCodes.Leave_S, (byte)0);
|
||||
ilGenerator.Emit(OpCodes.Ldloc, local);
|
||||
|
@ -2809,7 +2812,7 @@ class Compiler
|
|||
}
|
||||
else
|
||||
{
|
||||
LocalBuilder local = ilGenerator.DeclareLocal(args[i].TypeAsParameterType);
|
||||
LocalBuilder local = ilGenerator.DeclareLocal(args[i].TypeAsSignatureType);
|
||||
ilGenerator.Emit(OpCodes.Ldloca, local);
|
||||
dh.Load(i);
|
||||
ilGenerator.Emit(OpCodes.Stfld, args[i].GhostRefField);
|
||||
|
@ -2817,7 +2820,7 @@ class Compiler
|
|||
// NOTE when the this argument is a value type, we need the address on the stack instead of the value
|
||||
if(i != 0 || !instanceMethod)
|
||||
{
|
||||
ilGenerator.Emit(OpCodes.Ldobj, args[i].TypeAsParameterType);
|
||||
ilGenerator.Emit(OpCodes.Ldobj, args[i].TypeAsSignatureType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2843,7 +2846,7 @@ class Compiler
|
|||
}
|
||||
else if(ma.GetRawStackTypeWrapper(instructionIndex, args.Length - 1 - i).IsUnloadable)
|
||||
{
|
||||
ilGenerator.Emit(OpCodes.Castclass, args[i].TypeAsParameterType);
|
||||
ilGenerator.Emit(OpCodes.Castclass, args[i].TypeAsSignatureType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2925,16 +2928,14 @@ class Compiler
|
|||
if(!write)
|
||||
{
|
||||
field.EmitGet(ilGenerator);
|
||||
field.FieldTypeWrapper.EmitConvSignatureTypeToStackType(ilGenerator);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
TypeWrapper tw = field.FieldTypeWrapper;
|
||||
TypeWrapper val = ma.GetRawStackTypeWrapper(i, 0);
|
||||
if(!tw.IsUnloadable && (val.IsUnloadable || (tw.IsInterfaceOrInterfaceArray && !tw.IsGhost && !val.IsAssignableTo(tw))))
|
||||
{
|
||||
ilGenerator.Emit(OpCodes.Castclass, tw.TypeAsTBD);
|
||||
}
|
||||
tw.EmitConvStackTypeToSignatureType(ilGenerator, val);
|
||||
field.EmitSet(ilGenerator);
|
||||
return;
|
||||
}
|
||||
|
@ -2972,6 +2973,10 @@ class Compiler
|
|||
// NOTE we don't need to use TypeWrapper.EmitUnbox, because the return value cannot be null
|
||||
ilgen.Emit(OpCodes.Unbox, typeWrapper.TypeAsTBD);
|
||||
ilgen.Emit(OpCodes.Ldobj, typeWrapper.TypeAsTBD);
|
||||
if(typeWrapper == PrimitiveTypeWrapper.BYTE)
|
||||
{
|
||||
ilgen.Emit(OpCodes.Conv_I1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2989,7 +2994,7 @@ class Compiler
|
|||
private ClassFile.ConstantPoolItemMI cpi;
|
||||
|
||||
internal DynamicMethodWrapper(ClassLoaderWrapper classLoader, TypeWrapper wrapper, ClassFile.ConstantPoolItemMI cpi)
|
||||
: base(wrapper, null, null, null, null, null, Modifiers.Public, MemberFlags.None)
|
||||
: base(wrapper, cpi.Name, cpi.Signature, null, cpi.GetRetType(), cpi.GetArgTypes(), Modifiers.Public, MemberFlags.None)
|
||||
{
|
||||
this.classLoader = classLoader;
|
||||
this.wrapper = wrapper;
|
||||
|
|
|
@ -145,9 +145,9 @@ namespace IKVM.Internal.MapXml
|
|||
}
|
||||
if(tw.IsGhost)
|
||||
{
|
||||
tw.EmitConvStackToParameterType(ilgen, tw);
|
||||
tw.EmitConvStackTypeToSignatureType(ilgen, tw);
|
||||
}
|
||||
temps[j] = ilgen.DeclareLocal(tw.TypeAsParameterType);
|
||||
temps[j] = ilgen.DeclareLocal(tw.TypeAsSignatureType);
|
||||
ilgen.Emit(OpCodes.Stloc, temps[j]);
|
||||
}
|
||||
for(int j = 0; j < temps.Length; j++)
|
||||
|
@ -672,8 +672,7 @@ namespace IKVM.Internal.MapXml
|
|||
{
|
||||
FieldWrapper fw = ClassLoaderWrapper.LoadClassCritical(Class).GetFieldWrapper(Name, Sig);
|
||||
fw.Link();
|
||||
// we don't use fw.EmitGet because we don't want automatic boxing and whatever
|
||||
ilgen.Emit(OpCodes.Ldfld, fw.GetField());
|
||||
fw.EmitGet(ilgen);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ using System.Collections;
|
|||
using System.Xml;
|
||||
using System.Diagnostics;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Text;
|
||||
using IKVM.Attributes;
|
||||
using IKVM.Runtime;
|
||||
|
||||
|
@ -99,7 +100,7 @@ namespace IKVM.Runtime
|
|||
{
|
||||
ArrayList list = new ArrayList();
|
||||
string cmdline = Environment.CommandLine;
|
||||
System.Text.StringBuilder sb = new System.Text.StringBuilder();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for(int i = 0; i < cmdline.Length;)
|
||||
{
|
||||
bool quoted = cmdline[i] == '"';
|
||||
|
@ -406,7 +407,7 @@ namespace IKVM.Internal
|
|||
// but in order for ILDASM/ILASM round tripping to work reliably, we have
|
||||
// to make sure that we don't produce resource names that'll cause ILDASM
|
||||
// to generate invalid filenames.
|
||||
System.Text.StringBuilder sb = new System.Text.StringBuilder("ikvm__", name.Length + 6);
|
||||
StringBuilder sb = new StringBuilder("ikvm__", name.Length + 6);
|
||||
foreach(char c in name)
|
||||
{
|
||||
if("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-+.()$#@~=&{}[]0123456789`".IndexOf(c) != -1)
|
||||
|
@ -1121,7 +1122,7 @@ namespace IKVM.Internal
|
|||
typeWrapper.helperTypeBuilder = typeWrapper.typeBuilder.DefineNestedType("__Helper", TypeAttributes.NestedPublic | TypeAttributes.Class);
|
||||
AttributeHelper.HideFromJava(typeWrapper.helperTypeBuilder);
|
||||
}
|
||||
helper = typeWrapper.helperTypeBuilder.DefineMethod(m.Name, MethodAttributes.Public | MethodAttributes.Static, typeWrapper.GetClassLoader().RetTypeWrapperFromSig(m.Sig).TypeAsParameterType, argTypes);
|
||||
helper = typeWrapper.helperTypeBuilder.DefineMethod(m.Name, MethodAttributes.Public | MethodAttributes.Static, typeWrapper.GetClassLoader().RetTypeWrapperFromSig(m.Sig).TypeAsSignatureType, argTypes);
|
||||
ILGenerator ilgen = helper.GetILGenerator();
|
||||
foreach(IKVM.Internal.MapXml.Class c in specialCases)
|
||||
{
|
||||
|
@ -1156,7 +1157,7 @@ namespace IKVM.Internal
|
|||
{
|
||||
MethodBuilder mbCore = null;
|
||||
Type[] paramTypes = typeWrapper.GetClassLoader().ArgTypeListFromSig(m.Sig);
|
||||
Type retType = typeWrapper.GetClassLoader().RetTypeWrapperFromSig(m.Sig).TypeAsParameterType;
|
||||
Type retType = typeWrapper.GetClassLoader().RetTypeWrapperFromSig(m.Sig).TypeAsSignatureType;
|
||||
|
||||
if(typeWrapper.shadowType.IsSealed && (m.Modifiers & IKVM.Internal.MapXml.MapModifiers.Static) == 0)
|
||||
{
|
||||
|
@ -1276,7 +1277,7 @@ namespace IKVM.Internal
|
|||
{
|
||||
if(instr is IKVM.Internal.MapXml.Ret)
|
||||
{
|
||||
this.ReturnType.EmitConvStackToParameterType(ilgen, null);
|
||||
this.ReturnType.EmitConvStackTypeToSignatureType(ilgen, null);
|
||||
}
|
||||
instr.Generate(context, ilgen);
|
||||
}
|
||||
|
@ -1309,7 +1310,7 @@ namespace IKVM.Internal
|
|||
}
|
||||
ilgen.Emit(OpCodes.Call, baseMethod);
|
||||
}
|
||||
this.ReturnType.EmitConvStackToParameterType(ilgen, null);
|
||||
this.ReturnType.EmitConvStackTypeToSignatureType(ilgen, null);
|
||||
ilgen.Emit(OpCodes.Ret);
|
||||
}
|
||||
ilgen.EmitLineNumberTable(mbCore);
|
||||
|
@ -1344,7 +1345,7 @@ namespace IKVM.Internal
|
|||
ilgen.Emit(OpCodes.Ldarg, (short)(i + 1));
|
||||
}
|
||||
ilgen.Emit(OpCodes.Callvirt, mbCore);
|
||||
this.ReturnType.EmitConvStackToParameterType(ilgen, null);
|
||||
this.ReturnType.EmitConvStackTypeToSignatureType(ilgen, null);
|
||||
ilgen.Emit(OpCodes.Ret);
|
||||
ilgen.MarkLabel(skip);
|
||||
ilgen.Emit(OpCodes.Pop);
|
||||
|
@ -1370,7 +1371,7 @@ namespace IKVM.Internal
|
|||
}
|
||||
mw.Link();
|
||||
mw.EmitCallvirt(ilgen);
|
||||
this.ReturnType.EmitConvStackToParameterType(ilgen, null);
|
||||
this.ReturnType.EmitConvStackTypeToSignatureType(ilgen, null);
|
||||
ilgen.Emit(OpCodes.Ret);
|
||||
ilgen.MarkLabel(skip);
|
||||
ilgen.Emit(OpCodes.Pop);
|
||||
|
@ -1385,7 +1386,7 @@ namespace IKVM.Internal
|
|||
{
|
||||
if(instr is IKVM.Internal.MapXml.Ret)
|
||||
{
|
||||
this.ReturnType.EmitConvStackToParameterType(ilgen, null);
|
||||
this.ReturnType.EmitConvStackTypeToSignatureType(ilgen, null);
|
||||
}
|
||||
instr.Generate(context, ilgen);
|
||||
}
|
||||
|
@ -1428,7 +1429,7 @@ namespace IKVM.Internal
|
|||
}
|
||||
ilgen.Emit(OpCodes.Callvirt, overrideMethod);
|
||||
}
|
||||
this.ReturnType.EmitConvStackToParameterType(ilgen, null);
|
||||
this.ReturnType.EmitConvStackTypeToSignatureType(ilgen, null);
|
||||
ilgen.Emit(OpCodes.Ret);
|
||||
}
|
||||
ilgen.EmitLineNumberTable(mbHelper);
|
||||
|
@ -1439,7 +1440,7 @@ namespace IKVM.Internal
|
|||
{
|
||||
RemapperTypeWrapper typeWrapper = (RemapperTypeWrapper)DeclaringType;
|
||||
Type[] argTypes = new Type[paramTypes.Length + 1];
|
||||
argTypes[0] = typeWrapper.TypeAsParameterType;
|
||||
argTypes[0] = typeWrapper.TypeAsSignatureType;
|
||||
this.GetParametersForDefineMethod().CopyTo(argTypes, 1);
|
||||
MethodBuilder mb = typeWrapper.typeBuilder.DefineMethod("nonvirtualhelper/" + this.Name, MethodAttributes.Private | MethodAttributes.Static, this.ReturnTypeForDefineMethod, argTypes);
|
||||
AttributeHelper.HideFromJava(mb);
|
||||
|
@ -1504,13 +1505,6 @@ namespace IKVM.Internal
|
|||
mw.Link();
|
||||
mw.EmitCall(ilgen);
|
||||
}
|
||||
if(!classLoader.RetTypeWrapperFromSig(redirSig).IsAssignableTo(this.ReturnType))
|
||||
{
|
||||
// NOTE we're passing a null context, this is safe because the return type
|
||||
// should always be loadable
|
||||
System.Diagnostics.Debug.Assert(!this.ReturnType.IsUnloadable);
|
||||
this.ReturnType.EmitCheckcast(null, ilgen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1570,7 +1564,7 @@ namespace IKVM.Internal
|
|||
{
|
||||
attr |= FieldAttributes.InitOnly;
|
||||
}
|
||||
FieldBuilder fb = tb.DefineField(f.Name, GetClassLoader().FieldTypeWrapperFromSig(f.Sig).TypeAsFieldType, attr);
|
||||
FieldBuilder fb = tb.DefineField(f.Name, GetClassLoader().FieldTypeWrapperFromSig(f.Sig).TypeAsSignatureType, attr);
|
||||
object constant;
|
||||
if(f.Constant != null)
|
||||
{
|
||||
|
@ -1649,6 +1643,9 @@ namespace IKVM.Internal
|
|||
// sure the inherited methods don't show up in Intellisense.
|
||||
Hashtable methods = new Hashtable();
|
||||
foreach(MethodInfo mi in typeBuilder.BaseType.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static))
|
||||
{
|
||||
string key = MakeMethodKey(mi);
|
||||
if(!methods.ContainsKey(key))
|
||||
{
|
||||
ParameterInfo[] paramInfo = mi.GetParameters();
|
||||
Type[] paramTypes = new Type[paramInfo.Length];
|
||||
|
@ -1670,7 +1667,8 @@ namespace IKVM.Internal
|
|||
}
|
||||
ilgen.Emit(OpCodes.Call, mi);
|
||||
ilgen.Emit(OpCodes.Ret);
|
||||
methods[mb.Name] = mb;
|
||||
methods[key] = mb;
|
||||
}
|
||||
}
|
||||
foreach(PropertyInfo pi in typeBuilder.BaseType.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static))
|
||||
{
|
||||
|
@ -1683,11 +1681,11 @@ namespace IKVM.Internal
|
|||
PropertyBuilder pb = typeBuilder.DefineProperty(pi.Name, pi.Attributes, pi.PropertyType, paramTypes);
|
||||
if(pi.CanRead)
|
||||
{
|
||||
pb.SetGetMethod((MethodBuilder)methods[pi.GetGetMethod().Name]);
|
||||
pb.SetGetMethod((MethodBuilder)methods[MakeMethodKey(pi.GetGetMethod())]);
|
||||
}
|
||||
if(pi.CanWrite)
|
||||
{
|
||||
pb.SetSetMethod((MethodBuilder)methods[pi.GetSetMethod().Name]);
|
||||
pb.SetSetMethod((MethodBuilder)methods[MakeMethodKey(pi.GetSetMethod())]);
|
||||
}
|
||||
AttributeHelper.SetEditorBrowsableNever(pb);
|
||||
}
|
||||
|
@ -1700,6 +1698,20 @@ namespace IKVM.Internal
|
|||
}
|
||||
}
|
||||
|
||||
private static string MakeMethodKey(MethodInfo method)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.Append(method.ReturnType.AssemblyQualifiedName).Append(":").Append(method.Name);
|
||||
ParameterInfo[] paramInfo = method.GetParameters();
|
||||
Type[] paramTypes = new Type[paramInfo.Length];
|
||||
for(int i = 0; i < paramInfo.Length; i++)
|
||||
{
|
||||
paramTypes[i] = paramInfo[i].ParameterType;
|
||||
sb.Append(":").Append(paramInfo[i].ParameterType.AssemblyQualifiedName);
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private void CreateShadowInstanceOf(ICollection remappedTypes)
|
||||
{
|
||||
// FXBUG .NET 1.1 doesn't allow static methods on interfaces
|
||||
|
|
Загрузка…
Ссылка в новой задаче