зеркало из 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
|
// You can specify all the values or you can default the Revision and Build Numbers
|
||||||
// by using the '*' as shown below:
|
// 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
|
// 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
|
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 java.awt.EventQueue eventQueue = new java.awt.EventQueue();
|
||||||
private static volatile Form bogusForm;
|
private static volatile Form bogusForm;
|
||||||
private static Delegate createControlInstance;
|
private static Delegate createControlInstance;
|
||||||
|
@ -372,7 +373,7 @@ namespace ikvm.awt
|
||||||
return img;
|
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();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
@ -440,6 +441,42 @@ namespace ikvm.awt
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
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
|
class NetFontPeer : gnu.java.awt.peer.ClasspathFontPeer
|
||||||
|
@ -469,7 +506,7 @@ namespace ikvm.awt
|
||||||
throw new NotImplementedException();
|
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();
|
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)
|
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)
|
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");
|
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");
|
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"?>
|
<?xml version="1.0"?>
|
||||||
<project name="IKVM.GNU.Classpath.dll" default="IKVM.GNU.Classpath.dll">
|
<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 name="pathsep" value=":" />
|
||||||
<property overwrite="false" name="signoption" value="" />
|
<property overwrite="false" name="signoption" value="" />
|
||||||
|
<property name="jikes.compiler" value="true" />
|
||||||
|
<property name="ecj.compiler" value="false" />
|
||||||
|
|
||||||
<if propertytrue="nant.platform.win32">
|
<if propertytrue="nant.platform.win32">
|
||||||
<property name="pathsep" value=";" />
|
<property name="pathsep" value=";" />
|
||||||
|
@ -25,22 +27,27 @@
|
||||||
<includes name="**.class"/>
|
<includes name="**.class"/>
|
||||||
</fileset>
|
</fileset>
|
||||||
</delete>
|
</delete>
|
||||||
<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" />
|
<if propertytrue="jikes.compiler">
|
||||||
<exec program="jikes" commandline="-g -nowarn -classpath ${classpath} @allsources.lst"/>
|
<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>
|
||||||
|
|
||||||
<target name="IKVM.GNU.Classpath.dll" depends="classes">
|
<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" />
|
<copy file="IKVM.GNU.Classpath.dll" tofile="../bin/IKVM.GNU.Classpath.dll.new" />
|
||||||
<if propertytrue="nant.platform.win32">
|
<if propertytrue="nant.platform.win32">
|
||||||
<call target="peverify-classpath"/>
|
<call target="peverify-classpath"/>
|
||||||
</if>
|
</if>
|
||||||
<copy file="IKVM.GNU.Classpath.dll" todir="../bin" />
|
<copy file="IKVM.GNU.Classpath.dll" todir="../bin" />
|
||||||
<delete file="../bin/IKVM.GNU.Classpath.dll.new" />
|
<delete file="../bin/IKVM.GNU.Classpath.dll.new" />
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
<target name="peverify-classpath">
|
<target name="peverify-classpath">
|
||||||
<exec program="peverify" commandline="../bin/IKVM.GNU.Classpath.dll.new" />
|
<exec program="peverify" commandline="../bin/IKVM.GNU.Classpath.dll.new" />
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -45,7 +45,7 @@ public interface Configuration
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
String CLASSPATH_HOME = "";
|
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.ProtocolType;
|
||||||
import cli.System.Net.Sockets.AddressFamily;
|
import cli.System.Net.Sockets.AddressFamily;
|
||||||
import ikvm.lang.CIL;
|
import ikvm.lang.CIL;
|
||||||
import ikvm.lang.ByteArrayHack;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the default socket implementation for datagram sockets.
|
* This is the default socket implementation for datagram sockets.
|
||||||
|
@ -166,7 +165,7 @@ public class PlainDatagramSocketImpl extends DatagramSocketImpl
|
||||||
{
|
{
|
||||||
throw new SocketException("Invalid port");
|
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");
|
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.Net.Sockets.SocketException();
|
||||||
if(false) throw new cli.System.ObjectDisposedException("");
|
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);
|
cli.System.Net.Sockets.SocketFlags.wrap(cli.System.Net.Sockets.SocketFlags.None), remoteEP);
|
||||||
setDatagramPacketLength(packet, length);
|
setDatagramPacketLength(packet, length);
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,6 @@ import cli.System.Net.Sockets.ProtocolType;
|
||||||
import cli.System.Net.Sockets.AddressFamily;
|
import cli.System.Net.Sockets.AddressFamily;
|
||||||
import cli.System.Net.Sockets.SocketShutdown;
|
import cli.System.Net.Sockets.SocketShutdown;
|
||||||
import ikvm.lang.CIL;
|
import ikvm.lang.CIL;
|
||||||
import ikvm.lang.ByteArrayHack;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unless the application installs its own SocketImplFactory, this is the
|
* 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.Net.Sockets.SocketException();
|
||||||
if(false) throw new cli.System.ObjectDisposedException("");
|
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)
|
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.Net.Sockets.SocketException();
|
||||||
if(false) throw new cli.System.ObjectDisposedException("");
|
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)
|
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.Net.Sockets.SocketException();
|
||||||
if(false) throw new cli.System.ObjectDisposedException("");
|
if(false) throw new cli.System.ObjectDisposedException("");
|
||||||
byte[] oob = { (byte)data };
|
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)
|
catch(cli.System.Net.Sockets.SocketException x)
|
||||||
{
|
{
|
||||||
|
|
|
@ -81,20 +81,28 @@ class IkvmresURLConnection extends URLConnection
|
||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ResourceReader r = new ResourceReader(s);
|
Object r;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
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
|
try
|
||||||
{
|
{
|
||||||
IEnumerator e = r.GetEnumerator();
|
IEnumerator e = ((IEnumerable)r).GetEnumerator();
|
||||||
if(!e.MoveNext())
|
if(!e.MoveNext())
|
||||||
{
|
{
|
||||||
throw new IOException("invalid resource " + resource + " found in assembly " + assembly);
|
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;
|
connected = true;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
r.Close();
|
((cli.System.IDisposable)r).Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
|
|
|
@ -55,7 +55,6 @@ import java.nio.channels.WritableByteChannel;
|
||||||
|
|
||||||
import cli.System.Console;
|
import cli.System.Console;
|
||||||
import cli.System.IO.*;
|
import cli.System.IO.*;
|
||||||
import ikvm.lang.ByteArrayHack;
|
|
||||||
import ikvm.lang.CIL;
|
import ikvm.lang.CIL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -382,7 +381,7 @@ public final class FileChannelImpl extends FileChannel
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(false) throw new cli.System.IO.IOException();
|
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)
|
if(count == 0)
|
||||||
{
|
{
|
||||||
count = -1;
|
count = -1;
|
||||||
|
@ -416,6 +415,7 @@ public final class FileChannelImpl extends FileChannel
|
||||||
{
|
{
|
||||||
byte[] buffer = src.array();
|
byte[] buffer = src.array();
|
||||||
write(buffer, src.arrayOffset() + src.position(), len);
|
write(buffer, src.arrayOffset() + src.position(), len);
|
||||||
|
src.position(src.position() + len);
|
||||||
}
|
}
|
||||||
else
|
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.IO.IOException();
|
||||||
if(false) throw new cli.System.ObjectDisposedException(null);
|
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
|
// NOTE FileStream buffers the output, so we have to flush explicitly
|
||||||
stream.Flush();
|
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.IO.IOException();
|
||||||
if(false) throw new cli.System.ObjectDisposedException(null);
|
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
|
// NOTE FileStream buffers the output, so we have to flush explicitly
|
||||||
stream.Flush();
|
stream.Flush();
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,7 @@ public interface LibraryVMInterface
|
||||||
|
|
||||||
void jniWaitUntilLastThread();
|
void jniWaitUntilLastThread();
|
||||||
void jniDetach();
|
void jniDetach();
|
||||||
|
void setThreadGroup(Object group);
|
||||||
|
|
||||||
Object newConstructor(Object clazz, Object wrapper);
|
Object newConstructor(Object clazz, Object wrapper);
|
||||||
Object newMethod(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;
|
package ikvm.lang;
|
||||||
|
|
||||||
|
/** @deprecated */
|
||||||
public final class ByteArrayHack
|
public final class ByteArrayHack
|
||||||
{
|
{
|
||||||
private ByteArrayHack() {}
|
private ByteArrayHack() {}
|
||||||
|
|
||||||
public static native cli.System.Byte[] cast(byte[] b);
|
public static byte[] cast(byte[] b)
|
||||||
public static native byte[] cast(cli.System.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
|
This software is provided 'as-is', without any express or implied
|
||||||
warranty. In no event will the authors be held liable for any damages
|
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_long(long v);
|
||||||
public static native Object box_double(double 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.UInt16 box_ushort(short v);
|
||||||
public static native cli.System.UInt32 box_uint(int v);
|
public static native cli.System.UInt32 box_uint(int v);
|
||||||
public static native cli.System.UInt64 box_ulong(long 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 short unbox_ushort(cli.System.UInt16 v);
|
||||||
public static native int unbox_uint(cli.System.UInt32 v);
|
public static native int unbox_uint(cli.System.UInt32 v);
|
||||||
public static native long unbox_ulong(cli.System.UInt64 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
|
This software is provided 'as-is', without any express or implied
|
||||||
warranty. In no event will the authors be held liable for any damages
|
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)
|
public Object box(Object val)
|
||||||
{
|
{
|
||||||
if(val instanceof cli.System.SByte)
|
if(val instanceof cli.System.Byte)
|
||||||
{
|
{
|
||||||
return new Byte(CIL.unbox_byte(val));
|
return new Byte(CIL.unbox_byte(val));
|
||||||
}
|
}
|
||||||
|
@ -189,12 +189,17 @@ class LibraryVMInterfaceImpl implements ikvm.internal.LibraryVMInterface
|
||||||
VMThread.jniDetach();
|
VMThread.jniDetach();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setThreadGroup(Object group)
|
||||||
|
{
|
||||||
|
VMThread.setThreadGroup((ThreadGroup)group);
|
||||||
|
}
|
||||||
|
|
||||||
public native Object newDirectByteBuffer(cli.System.IntPtr address, int capacity);
|
public native Object newDirectByteBuffer(cli.System.IntPtr address, int capacity);
|
||||||
public native cli.System.IntPtr getDirectBufferAddress(Object buffer);
|
public native cli.System.IntPtr getDirectBufferAddress(Object buffer);
|
||||||
|
|
||||||
public int getDirectBufferCapacity(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)
|
public void setProperties(cli.System.Collections.Hashtable props)
|
||||||
|
|
|
@ -45,6 +45,7 @@ import java.util.Enumeration;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import gnu.classpath.SystemProperties;
|
import gnu.classpath.SystemProperties;
|
||||||
|
@ -173,31 +174,34 @@ final class VMClassLoader
|
||||||
*/
|
*/
|
||||||
static Enumeration getResources(String name) throws IOException
|
static Enumeration getResources(String name) throws IOException
|
||||||
{
|
{
|
||||||
if(cli.System.Threading.Thread.GetData(nestedGetResourcesHack) != null)
|
synchronized(nestedGetResourcesHack)
|
||||||
{
|
{
|
||||||
return gnu.java.util.EmptyEnumeration.getInstance();
|
if(cli.System.Threading.Thread.GetData(nestedGetResourcesHack) != null)
|
||||||
}
|
|
||||||
cli.System.Threading.Thread.SetData(nestedGetResourcesHack, "");
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Assembly[] assemblies = findResourceAssemblies(name);
|
|
||||||
java.util.Vector v = new java.util.Vector();
|
|
||||||
for(int i = 0; i < assemblies.length; i++)
|
|
||||||
{
|
{
|
||||||
v.addElement(new URL("ikvmres", assemblies[i].get_FullName(), -1, "/" + name));
|
return gnu.java.util.EmptyEnumeration.getInstance();
|
||||||
}
|
}
|
||||||
Enumeration e = v.elements();
|
cli.System.Threading.Thread.SetData(nestedGetResourcesHack, "");
|
||||||
ClassLoader bootstrap = getBootstrapClassLoader();
|
try
|
||||||
if(bootstrap != null)
|
|
||||||
{
|
{
|
||||||
e = new DoubleEnumeration(e, bootstrap.getResources(name));
|
Assembly[] assemblies = findResourceAssemblies(name);
|
||||||
|
java.util.Vector v = new java.util.Vector();
|
||||||
|
for(int i = 0; i < assemblies.length; i++)
|
||||||
|
{
|
||||||
|
v.addElement(new URL("ikvmres", assemblies[i].get_FullName(), -1, "/" + name));
|
||||||
|
}
|
||||||
|
Enumeration e = v.elements();
|
||||||
|
ClassLoader bootstrap = getBootstrapClassLoader();
|
||||||
|
if(bootstrap != null)
|
||||||
|
{
|
||||||
|
e = new DoubleEnumeration(e, bootstrap.getResources(name));
|
||||||
|
}
|
||||||
|
return e;
|
||||||
}
|
}
|
||||||
return e;
|
finally
|
||||||
}
|
{
|
||||||
finally
|
cli.System.Threading.Thread.SetData(nestedGetResourcesHack, null);
|
||||||
{
|
}
|
||||||
cli.System.Threading.Thread.SetData(nestedGetResourcesHack, null);
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static cli.System.LocalDataStoreSlot nestedGetResourcesHack = cli.System.Threading.Thread.AllocateDataSlot();
|
private static cli.System.LocalDataStoreSlot nestedGetResourcesHack = cli.System.Threading.Thread.AllocateDataSlot();
|
||||||
|
@ -212,6 +216,14 @@ final class VMClassLoader
|
||||||
*/
|
*/
|
||||||
static Package getPackage(String name)
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,9 +236,96 @@ final class VMClassLoader
|
||||||
*/
|
*/
|
||||||
static Package[] getPackages()
|
static Package[] getPackages()
|
||||||
{
|
{
|
||||||
return new Package[0];
|
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
|
* Helper for java.lang.Integer, Byte, etc to get the TYPE class
|
||||||
* at initialization time. The type code is one of the chars that
|
* at initialization time. The type code is one of the chars that
|
||||||
|
|
|
@ -189,7 +189,7 @@ final class VMRuntime
|
||||||
* @param filename the file to load
|
* @param filename the file to load
|
||||||
* @return 0 on failure, nonzero on success
|
* @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.
|
* 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)
|
static void create(Thread thread, long stacksize)
|
||||||
{
|
{
|
||||||
VMThread vmThread = new VMThread(thread);
|
VMThread vmThread = new VMThread(thread);
|
||||||
|
@ -463,50 +472,56 @@ final class VMThread
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
vmThread.nativeThreadReference = new cli.System.WeakReference(nativeThread);
|
||||||
|
vmThread.running = true;
|
||||||
|
int priority = Thread.NORM_PRIORITY;
|
||||||
|
switch(nativeThread.get_Priority().Value)
|
||||||
|
{
|
||||||
|
case cli.System.Threading.ThreadPriority.Lowest:
|
||||||
|
priority = Thread.MIN_PRIORITY;
|
||||||
|
break;
|
||||||
|
case cli.System.Threading.ThreadPriority.BelowNormal:
|
||||||
|
priority = 3;
|
||||||
|
break;
|
||||||
|
case cli.System.Threading.ThreadPriority.Normal:
|
||||||
|
priority = Thread.NORM_PRIORITY;
|
||||||
|
break;
|
||||||
|
case cli.System.Threading.ThreadPriority.AboveNormal:
|
||||||
|
priority = 7;
|
||||||
|
break;
|
||||||
|
case cli.System.Threading.ThreadPriority.Highest:
|
||||||
|
priority = Thread.MAX_PRIORITY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Thread javaThread = new Thread(vmThread, nativeThread.get_Name(), priority, nativeThread.get_IsBackground());
|
||||||
|
if(!javaThread.daemon)
|
||||||
|
{
|
||||||
|
synchronized(countLock)
|
||||||
|
{
|
||||||
|
nonDaemonCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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));
|
||||||
|
javaThread.group = group;
|
||||||
|
javaThread.group.addThread(javaThread);
|
||||||
|
InheritableThreadLocal.newChildThread(javaThread);
|
||||||
|
return javaThread;
|
||||||
|
}
|
||||||
|
|
||||||
static Thread currentThread()
|
static Thread currentThread()
|
||||||
{
|
{
|
||||||
Thread javaThread = (Thread)cli.System.Threading.Thread.GetData(localDataStoreSlot);
|
Thread javaThread = (Thread)cli.System.Threading.Thread.GetData(localDataStoreSlot);
|
||||||
if(javaThread == null)
|
if(javaThread == null)
|
||||||
{
|
{
|
||||||
cli.System.Threading.Thread nativeThread = cli.System.Threading.Thread.get_CurrentThread();
|
javaThread = newThread(ThreadGroup.root);
|
||||||
VMThread vmThread = new VMThread(null);
|
|
||||||
vmThread.nativeThreadReference = new cli.System.WeakReference(nativeThread);
|
|
||||||
vmThread.running = true;
|
|
||||||
int priority = Thread.NORM_PRIORITY;
|
|
||||||
switch(nativeThread.get_Priority().Value)
|
|
||||||
{
|
|
||||||
case cli.System.Threading.ThreadPriority.Lowest:
|
|
||||||
priority = Thread.MIN_PRIORITY;
|
|
||||||
break;
|
|
||||||
case cli.System.Threading.ThreadPriority.BelowNormal:
|
|
||||||
priority = 3;
|
|
||||||
break;
|
|
||||||
case cli.System.Threading.ThreadPriority.Normal:
|
|
||||||
priority = Thread.NORM_PRIORITY;
|
|
||||||
break;
|
|
||||||
case cli.System.Threading.ThreadPriority.AboveNormal:
|
|
||||||
priority = 7;
|
|
||||||
break;
|
|
||||||
case cli.System.Threading.ThreadPriority.Highest:
|
|
||||||
priority = Thread.MAX_PRIORITY;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
javaThread = new Thread(vmThread, nativeThread.get_Name(), priority, nativeThread.get_IsBackground());
|
|
||||||
if(!javaThread.daemon)
|
|
||||||
{
|
|
||||||
synchronized(countLock)
|
|
||||||
{
|
|
||||||
nonDaemonCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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.addThread(javaThread);
|
|
||||||
InheritableThreadLocal.newChildThread(javaThread);
|
|
||||||
}
|
}
|
||||||
return javaThread;
|
return javaThread;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@ exception statement from your version. */
|
||||||
package java.lang.reflect;
|
package java.lang.reflect;
|
||||||
|
|
||||||
import cli.System.Diagnostics.StackFrame;
|
import cli.System.Diagnostics.StackFrame;
|
||||||
|
import gnu.classpath.VMStackWalker;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Constructor class represents a constructor of a class. It also allows
|
* The Constructor class represents a constructor of a class. It also allows
|
||||||
|
@ -259,7 +260,7 @@ public final class Constructor
|
||||||
InvocationTargetException
|
InvocationTargetException
|
||||||
{
|
{
|
||||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
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);
|
int mods = declaringClass.getModifiers() | Method.GetRealModifiers(declaringClass);
|
||||||
if(Modifier.isAbstract(mods) || Modifier.isInterface(mods))
|
if(Modifier.isAbstract(mods) || Modifier.isInterface(mods))
|
||||||
{
|
{
|
||||||
|
|
|
@ -39,6 +39,7 @@ exception statement from your version. */
|
||||||
package java.lang.reflect;
|
package java.lang.reflect;
|
||||||
|
|
||||||
import cli.System.Diagnostics.StackFrame;
|
import cli.System.Diagnostics.StackFrame;
|
||||||
|
import gnu.classpath.VMStackWalker;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Field class represents a member variable of a class. It also allows
|
* 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
|
throws IllegalAccessException
|
||||||
{
|
{
|
||||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
||||||
checkAccess(modifiers, o, declaringClass, new StackFrame(1));
|
checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
|
||||||
return GetValue(fieldCookie, o);
|
return GetValue(fieldCookie, o);
|
||||||
}
|
}
|
||||||
private static native Object GetValue(Object fieldCookie, Object o);
|
private static native Object GetValue(Object fieldCookie, Object o);
|
||||||
|
@ -262,7 +263,7 @@ public final class Field extends AccessibleObject implements Member
|
||||||
throws IllegalAccessException
|
throws IllegalAccessException
|
||||||
{
|
{
|
||||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
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();
|
return ((Boolean)GetValue(fieldCookie, o)).booleanValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,7 +288,7 @@ public final class Field extends AccessibleObject implements Member
|
||||||
throws IllegalAccessException
|
throws IllegalAccessException
|
||||||
{
|
{
|
||||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
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();
|
return ((Byte)GetValue(fieldCookie, o)).byteValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,7 +311,7 @@ public final class Field extends AccessibleObject implements Member
|
||||||
throws IllegalAccessException
|
throws IllegalAccessException
|
||||||
{
|
{
|
||||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
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();
|
return ((Character)GetValue(fieldCookie, o)).charValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -335,7 +336,7 @@ public final class Field extends AccessibleObject implements Member
|
||||||
throws IllegalAccessException
|
throws IllegalAccessException
|
||||||
{
|
{
|
||||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
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();
|
return ((Short)GetValue(fieldCookie, o)).shortValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,7 +361,7 @@ public final class Field extends AccessibleObject implements Member
|
||||||
throws IllegalAccessException
|
throws IllegalAccessException
|
||||||
{
|
{
|
||||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
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();
|
return ((Integer)GetValue(fieldCookie, o)).intValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -385,7 +386,7 @@ public final class Field extends AccessibleObject implements Member
|
||||||
throws IllegalAccessException
|
throws IllegalAccessException
|
||||||
{
|
{
|
||||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
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();
|
return ((Long)GetValue(fieldCookie, o)).longValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -410,7 +411,7 @@ public final class Field extends AccessibleObject implements Member
|
||||||
throws IllegalAccessException
|
throws IllegalAccessException
|
||||||
{
|
{
|
||||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
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();
|
return ((Float)GetValue(fieldCookie, o)).floatValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -436,7 +437,7 @@ public final class Field extends AccessibleObject implements Member
|
||||||
throws IllegalAccessException
|
throws IllegalAccessException
|
||||||
{
|
{
|
||||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
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();
|
return ((Double)GetValue(fieldCookie, o)).doubleValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -489,17 +490,16 @@ public final class Field extends AccessibleObject implements Member
|
||||||
throws IllegalAccessException
|
throws IllegalAccessException
|
||||||
{
|
{
|
||||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
||||||
checkAccess(modifiers, o, declaringClass, new StackFrame(1));
|
checkAccess(modifiers, o, declaringClass, VMStackWalker.getCallingClass());
|
||||||
SetValue(fieldCookie, o, value);
|
SetValue(fieldCookie, o, value);
|
||||||
}
|
}
|
||||||
private static native void SetValue(Object fieldCookie, Object o, Object 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.
|
// 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();
|
Class actualClass = Modifier.isStatic(modifiers) || o == null ? declaringClass : o.getClass();
|
||||||
boolean declaringClassIsPublic = (Method.GetRealModifiers(declaringClass) & Modifier.PUBLIC) != 0;
|
boolean declaringClassIsPublic = (Method.GetRealModifiers(declaringClass) & Modifier.PUBLIC) != 0;
|
||||||
Class caller = getClassFromFrame(frame);
|
|
||||||
if((!Modifier.isPublic(modifiers) || !declaringClassIsPublic) && declaringClass != caller)
|
if((!Modifier.isPublic(modifiers) || !declaringClassIsPublic) && declaringClass != caller)
|
||||||
{
|
{
|
||||||
// if the caller is a global method, the class returned will be null
|
// 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))
|
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 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
|
* 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
|
throws IllegalAccessException
|
||||||
{
|
{
|
||||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
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));
|
SetValue(fieldCookie, o, new Boolean(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -565,7 +566,7 @@ public final class Field extends AccessibleObject implements Member
|
||||||
throws IllegalAccessException
|
throws IllegalAccessException
|
||||||
{
|
{
|
||||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
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));
|
SetValue(fieldCookie, o, new Byte(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -590,7 +591,7 @@ public final class Field extends AccessibleObject implements Member
|
||||||
throws IllegalAccessException
|
throws IllegalAccessException
|
||||||
{
|
{
|
||||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
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));
|
SetValue(fieldCookie, o, new Character(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -615,7 +616,7 @@ public final class Field extends AccessibleObject implements Member
|
||||||
throws IllegalAccessException
|
throws IllegalAccessException
|
||||||
{
|
{
|
||||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
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));
|
SetValue(fieldCookie, o, new Short(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -640,7 +641,7 @@ public final class Field extends AccessibleObject implements Member
|
||||||
throws IllegalAccessException
|
throws IllegalAccessException
|
||||||
{
|
{
|
||||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
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));
|
SetValue(fieldCookie, o, new Integer(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -665,7 +666,7 @@ public final class Field extends AccessibleObject implements Member
|
||||||
throws IllegalAccessException
|
throws IllegalAccessException
|
||||||
{
|
{
|
||||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
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));
|
SetValue(fieldCookie, o, new Long(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -690,7 +691,7 @@ public final class Field extends AccessibleObject implements Member
|
||||||
throws IllegalAccessException
|
throws IllegalAccessException
|
||||||
{
|
{
|
||||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
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));
|
SetValue(fieldCookie, o, new Float(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -715,7 +716,7 @@ public final class Field extends AccessibleObject implements Member
|
||||||
throws IllegalAccessException
|
throws IllegalAccessException
|
||||||
{
|
{
|
||||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
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));
|
SetValue(fieldCookie, o, new Double(value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@ exception statement from your version. */
|
||||||
package java.lang.reflect;
|
package java.lang.reflect;
|
||||||
|
|
||||||
import cli.System.Diagnostics.StackFrame;
|
import cli.System.Diagnostics.StackFrame;
|
||||||
|
import gnu.classpath.VMStackWalker;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Method class represents a member method of a class. It also allows
|
* 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
|
throws IllegalAccessException, InvocationTargetException
|
||||||
{
|
{
|
||||||
if(!isAccessible() && (!Modifier.isPublic(modifiers) || !classIsPublic))
|
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(!Modifier.isStatic(modifiers))
|
||||||
{
|
{
|
||||||
if(o == null)
|
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;
|
package java.nio;
|
||||||
|
|
||||||
import gnu.classpath.RawData;
|
import gnu.classpath.RawData;
|
||||||
|
@ -12,9 +35,9 @@ class VMDirectByteBuffer
|
||||||
return new DirectByteBufferImpl.ReadWrite(null, new RawData(p), capacity, capacity, 0);
|
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)
|
static RawData allocate(int capacity)
|
||||||
|
@ -35,7 +58,7 @@ class VMDirectByteBuffer
|
||||||
static void get(RawData r, int index, byte[] dst, int offset, int length)
|
static void get(RawData r, int index, byte[] dst, int offset, int length)
|
||||||
{
|
{
|
||||||
IntPtr address = new IntPtr(r.p().ToInt64() + index);
|
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)
|
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" ?>
|
<?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
|
This software is provided 'as-is', without any express or implied
|
||||||
warranty. In no event will the authors be held liable for any damages
|
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">
|
<constructor sig="(Ljava.lang.StringBuffer;)V" modifiers="public">
|
||||||
<redirect class="java.lang.StringHelper" name="NewString" type="static" sig="(Ljava.lang.StringBuffer;)Ljava.lang.String;" />
|
<redirect class="java.lang.StringHelper" name="NewString" type="static" sig="(Ljava.lang.StringBuffer;)Ljava.lang.String;" />
|
||||||
</constructor>
|
</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">
|
<constructor sig="([B)V" modifiers="public">
|
||||||
<redirect class="java.lang.StringHelper" name="NewString" type="static" sig="([B)Ljava.lang.String;" />
|
<redirect class="java.lang.StringHelper" name="NewString" type="static" sig="([B)Ljava.lang.String;" />
|
||||||
</constructor>
|
</constructor>
|
||||||
|
@ -644,7 +655,7 @@
|
||||||
<method name="unbox_byte" sig="(Ljava.lang.Object;)B">
|
<method name="unbox_byte" sig="(Ljava.lang.Object;)B">
|
||||||
<body>
|
<body>
|
||||||
<ldarg_0 />
|
<ldarg_0 />
|
||||||
<unbox type="System.SByte, mscorlib" />
|
<unbox type="System.Byte, mscorlib" />
|
||||||
<ldind_i1 />
|
<ldind_i1 />
|
||||||
<ret />
|
<ret />
|
||||||
</body>
|
</body>
|
||||||
|
@ -708,7 +719,7 @@
|
||||||
<method name="box_byte" sig="(B)Ljava.lang.Object;">
|
<method name="box_byte" sig="(B)Ljava.lang.Object;">
|
||||||
<body>
|
<body>
|
||||||
<ldarg_0 />
|
<ldarg_0 />
|
||||||
<box type="System.SByte, mscorlib" />
|
<box type="System.Byte, mscorlib" />
|
||||||
<ret />
|
<ret />
|
||||||
</body>
|
</body>
|
||||||
</method>
|
</method>
|
||||||
|
@ -761,7 +772,7 @@
|
||||||
<ret />
|
<ret />
|
||||||
</body>
|
</body>
|
||||||
</method>
|
</method>
|
||||||
<method name="box_ubyte" sig="(B)Lcli.System.Byte;">
|
<method name="box_sbyte" sig="(B)Lcli.System.SByte;">
|
||||||
<body>
|
<body>
|
||||||
<ldarg_0 />
|
<ldarg_0 />
|
||||||
<ret />
|
<ret />
|
||||||
|
@ -785,7 +796,7 @@
|
||||||
<ret />
|
<ret />
|
||||||
</body>
|
</body>
|
||||||
</method>
|
</method>
|
||||||
<method name="unbox_ubyte" sig="(Lcli.System.Byte;)B">
|
<method name="unbox_sbyte" sig="(Lcli.System.SByte;)B">
|
||||||
<body>
|
<body>
|
||||||
<ldarg_0 />
|
<ldarg_0 />
|
||||||
<ret />
|
<ret />
|
||||||
|
@ -810,20 +821,6 @@
|
||||||
</body>
|
</body>
|
||||||
</method>
|
</method>
|
||||||
</class>
|
</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">
|
<class name="java.lang.VMClass">
|
||||||
<method name="createField" sig="(Ljava.lang.Class;Ljava.lang.Object;)Ljava.lang.reflect.Field;">
|
<method name="createField" sig="(Ljava.lang.Class;Ljava.lang.Object;)Ljava.lang.reflect.Field;">
|
||||||
<body>
|
<body>
|
||||||
|
@ -883,11 +880,8 @@
|
||||||
<method name="getDirectBufferAddress" sig="(Ljava.lang.Object;)Lcli.System.IntPtr;">
|
<method name="getDirectBufferAddress" sig="(Ljava.lang.Object;)Lcli.System.IntPtr;">
|
||||||
<body>
|
<body>
|
||||||
<ldarg_1 />
|
<ldarg_1 />
|
||||||
<castclass class="java.nio.ByteBuffer" />
|
<castclass class="java.nio.Buffer" />
|
||||||
<call class="java.nio.VMDirectByteBuffer" name="GetDirectBufferAddress" sig="(Ljava.nio.ByteBuffer;)Lcli.System.IntPtr;" />
|
<call class="java.nio.VMDirectByteBuffer" name="GetDirectBufferAddress" sig="(Ljava.nio.Buffer;)Lcli.System.IntPtr;" />
|
||||||
<!-- LAME we need to unbox the return value -->
|
|
||||||
<unbox type="System.IntPtr, mscorlib" />
|
|
||||||
<ldobj type="System.IntPtr, mscorlib" />
|
|
||||||
<ret />
|
<ret />
|
||||||
</body>
|
</body>
|
||||||
</method>
|
</method>
|
||||||
|
@ -909,7 +903,7 @@
|
||||||
</body>
|
</body>
|
||||||
</method>
|
</method>
|
||||||
</class>
|
</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;">
|
<method name="newInputStream" sig="(Lgnu.java.nio.channels.FileChannelImpl;)Ljava.io.FileInputStream;">
|
||||||
<body>
|
<body>
|
||||||
<ldarg_0 />
|
<ldarg_0 />
|
||||||
|
@ -938,7 +932,7 @@
|
||||||
<ldarg_0 />
|
<ldarg_0 />
|
||||||
<ldfld class="java.nio.Buffer" name="pos" sig="I" />
|
<ldfld class="java.nio.Buffer" name="pos" sig="I" />
|
||||||
<call type="gnu.classpath.RawData" name="ReadByte" sig="(I)B" />
|
<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 />
|
||||||
<ldarg_0 />
|
<ldarg_0 />
|
||||||
<ldfld class="java.nio.Buffer" name="pos" sig="I" />
|
<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
|
// You can specify all the values or you can default the Revision and Build Numbers
|
||||||
// by using the '*' as shown below:
|
// 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
|
// 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
|
// You can specify all the values or you can default the Revision and Build Numbers
|
||||||
// by using the '*' as shown below:
|
// 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
|
// 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
|
// You can specify all the values or you can default the Revision and Build Numbers
|
||||||
// by using the '*' as shown below:
|
// 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
|
// 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)
|
if(constantValue != null)
|
||||||
{
|
{
|
||||||
ushort constantValueIndex;
|
ushort constantValueIndex;
|
||||||
if(constantValue is sbyte)
|
if(constantValue is byte)
|
||||||
{
|
{
|
||||||
constantValueIndex = AddInt((sbyte)constantValue);
|
constantValueIndex = AddInt((sbyte)(byte)constantValue);
|
||||||
}
|
}
|
||||||
else if(constantValue is bool)
|
else if(constantValue is bool)
|
||||||
{
|
{
|
||||||
|
@ -744,18 +744,10 @@ class ClassFileWriter
|
||||||
{
|
{
|
||||||
constantValueIndex = AddInt((int)constantValue);
|
constantValueIndex = AddInt((int)constantValue);
|
||||||
}
|
}
|
||||||
else if(constantValue is uint)
|
|
||||||
{
|
|
||||||
constantValueIndex = AddInt((int)(uint)constantValue);
|
|
||||||
}
|
|
||||||
else if(constantValue is long)
|
else if(constantValue is long)
|
||||||
{
|
{
|
||||||
constantValueIndex = AddLong((long)constantValue);
|
constantValueIndex = AddLong((long)constantValue);
|
||||||
}
|
}
|
||||||
else if(constantValue is ulong)
|
|
||||||
{
|
|
||||||
constantValueIndex = AddLong((long)(ulong)constantValue);
|
|
||||||
}
|
|
||||||
else if(constantValue is float)
|
else if(constantValue is float)
|
||||||
{
|
{
|
||||||
constantValueIndex = AddFloat((float)constantValue);
|
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
|
This software is provided 'as-is', without any express or implied
|
||||||
warranty. In no event will the authors be held liable for any damages
|
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.Text;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using ICSharpCode.SharpZipLib.Zip;
|
using ICSharpCode.SharpZipLib.Zip;
|
||||||
using java.lang;
|
|
||||||
using java.lang.reflect;
|
|
||||||
using IKVM.Attributes;
|
using IKVM.Attributes;
|
||||||
using IKVM.Internal;
|
using IKVM.Internal;
|
||||||
|
|
||||||
|
@ -79,6 +77,7 @@ public class NetExp
|
||||||
{
|
{
|
||||||
assembly = Assembly.LoadWithPartialName(args[0]);
|
assembly = Assembly.LoadWithPartialName(args[0]);
|
||||||
}
|
}
|
||||||
|
int rc = 0;
|
||||||
if(assembly == null)
|
if(assembly == null)
|
||||||
{
|
{
|
||||||
Console.Error.WriteLine("Error: Assembly \"{0}\" not found", args[0]);
|
Console.Error.WriteLine("Error: Assembly \"{0}\" not found", args[0]);
|
||||||
|
@ -94,12 +93,13 @@ public class NetExp
|
||||||
catch(System.Exception x)
|
catch(System.Exception x)
|
||||||
{
|
{
|
||||||
java.lang.Throwable.instancehelper_printStackTrace(IKVM.Runtime.Util.MapException(x));
|
java.lang.Throwable.instancehelper_printStackTrace(IKVM.Runtime.Util.MapException(x));
|
||||||
|
rc = 1;
|
||||||
}
|
}
|
||||||
zipFile.Close();
|
zipFile.Close();
|
||||||
}
|
}
|
||||||
// FXBUG if we run a static initializer that starts a thread, we would never end,
|
// FXBUG if we run a static initializer that starts a thread, we would never end,
|
||||||
// so we force an exit here
|
// so we force an exit here
|
||||||
Environment.Exit(0);
|
Environment.Exit(rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void WriteClass(string name, ClassFileWriter c)
|
private static void WriteClass(string name, ClassFileWriter c)
|
||||||
|
@ -114,12 +114,12 @@ public class NetExp
|
||||||
{
|
{
|
||||||
if(t.IsPublic)
|
if(t.IsPublic)
|
||||||
{
|
{
|
||||||
Class c;
|
java.lang.Class c;
|
||||||
try
|
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
|
// types that IKVM doesn't support don't show up
|
||||||
continue;
|
continue;
|
||||||
|
@ -139,7 +139,7 @@ public class NetExp
|
||||||
Hashtable todo = privateClasses;
|
Hashtable todo = privateClasses;
|
||||||
privateClasses = new Hashtable();
|
privateClasses = new Hashtable();
|
||||||
keepGoing = false;
|
keepGoing = false;
|
||||||
foreach(Class c in todo.Values)
|
foreach(java.lang.Class c in todo.Values)
|
||||||
{
|
{
|
||||||
if(!done.ContainsKey(c.getName()))
|
if(!done.ContainsKey(c.getName()))
|
||||||
{
|
{
|
||||||
|
@ -151,7 +151,7 @@ public class NetExp
|
||||||
} while(keepGoing);
|
} 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 name = c.getName().Replace('.', '/');
|
||||||
string super = null;
|
string super = null;
|
||||||
|
@ -159,7 +159,7 @@ public class NetExp
|
||||||
{
|
{
|
||||||
super = c.getSuperclass().getName().Replace('.', '/');
|
super = c.getSuperclass().getName().Replace('.', '/');
|
||||||
// if the base class isn't public, we still need to export it (!)
|
// 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();
|
privateClasses[c.getSuperclass().getName()] = c.getSuperclass();
|
||||||
}
|
}
|
||||||
|
@ -196,15 +196,15 @@ public class NetExp
|
||||||
}
|
}
|
||||||
innerClassesAttribute.Add(name, outer.getName().Replace('.', '/'), innername, (ushort)c.getModifiers());
|
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++)
|
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('.', '/'));
|
f.AddInterface(interfaces[i].getName().Replace('.', '/'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Class[] innerClasses = c.getDeclaredClasses();
|
java.lang.Class[] innerClasses = c.getDeclaredClasses();
|
||||||
for(int i = 0; i < innerClasses.Length; i++)
|
for(int i = 0; i < innerClasses.Length; i++)
|
||||||
{
|
{
|
||||||
Modifiers mods = (Modifiers)innerClasses[i].getModifiers();
|
Modifiers mods = (Modifiers)innerClasses[i].getModifiers();
|
||||||
|
@ -220,7 +220,7 @@ public class NetExp
|
||||||
ProcessClass(assemblyName, innerClasses[i], c);
|
ProcessClass(assemblyName, innerClasses[i], c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Constructor[] constructors = c.getDeclaredConstructors();
|
java.lang.reflect.Constructor[] constructors = c.getDeclaredConstructors();
|
||||||
for(int i = 0; i < constructors.Length; i++)
|
for(int i = 0; i < constructors.Length; i++)
|
||||||
{
|
{
|
||||||
Modifiers mods = (Modifiers)constructors[i].getModifiers();
|
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++)
|
for(int i = 0; i < methods.Length; i++)
|
||||||
{
|
{
|
||||||
Modifiers mods = (Modifiers)methods[i].getModifiers();
|
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++)
|
for(int i = 0; i < fields.Length; i++)
|
||||||
{
|
{
|
||||||
Modifiers mods = (Modifiers)fields[i].getModifiers();
|
Modifiers mods = (Modifiers)fields[i].getModifiers();
|
||||||
|
@ -340,12 +340,12 @@ public class NetExp
|
||||||
WriteClass(name + ".class", f);
|
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)
|
if(exceptions.Length > 0)
|
||||||
{
|
{
|
||||||
ExceptionsAttribute attrib = new ExceptionsAttribute(f);
|
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?
|
// TODO what happens if one of the exception types is non-public?
|
||||||
attrib.Add(x.getName().Replace('.', '/'));
|
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();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.Append('(');
|
sb.Append('(');
|
||||||
|
@ -367,7 +367,7 @@ public class NetExp
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string ClassToSig(Class c)
|
private static string ClassToSig(java.lang.Class c)
|
||||||
{
|
{
|
||||||
if(c.isPrimitive())
|
if(c.isPrimitive())
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
<property name="REFERENCE_API_NAME" value="JDK-1.5" />
|
<property name="REFERENCE_API_NAME" value="JDK-1.5" />
|
||||||
-->
|
-->
|
||||||
<property name="JAPI_HOME" value="c:\japi\japitools" />
|
<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">
|
<target name="default">
|
||||||
<call target="status" />
|
<call target="status" />
|
||||||
|
|
|
@ -23,12 +23,9 @@
|
||||||
*/
|
*/
|
||||||
.assembly JVM
|
.assembly JVM
|
||||||
{
|
{
|
||||||
.ver 0:10:0:1
|
.ver 0:11:0:0
|
||||||
}
|
}
|
||||||
.module JVM.DLL
|
.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)
|
.method public static int32 JNI_CreateJavaVM(void* ppvm, void* ppenv, void* args)
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
<target name="JVM">
|
<target name="JVM">
|
||||||
<property overwrite="false" name="ilasm_signoption" value="" />
|
<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="../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>
|
</target>
|
||||||
</project>
|
</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
|
// You can specify all the values or you can default the Revision and Build Numbers
|
||||||
// by using the '*' as shown below:
|
// 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
|
// 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))
|
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();
|
wrapper.Finish();
|
||||||
return wrapper;
|
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)
|
public static object DynamicInvokevirtual(object obj, RuntimeTypeHandle type, string clazz, string name, string sig, object[] args)
|
||||||
{
|
{
|
||||||
Profiler.Count("DynamicInvokevirtual");
|
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]
|
[DebuggerStepThroughAttribute]
|
||||||
|
|
|
@ -1117,7 +1117,19 @@ sealed class ClassFile
|
||||||
field = wrapper.GetFieldWrapper(Name, Signature);
|
field = wrapper.GetFieldWrapper(Name, Signature);
|
||||||
if(field != null)
|
if(field != null)
|
||||||
{
|
{
|
||||||
field.Link();
|
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);
|
constantValue = (short)classFile.GetConstantPoolConstantInteger(index);
|
||||||
break;
|
break;
|
||||||
case "B":
|
case "B":
|
||||||
constantValue = (sbyte)classFile.GetConstantPoolConstantInteger(index);
|
constantValue = (byte)classFile.GetConstantPoolConstantInteger(index);
|
||||||
break;
|
break;
|
||||||
case "C":
|
case "C":
|
||||||
constantValue = (char)classFile.GetConstantPoolConstantInteger(index);
|
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
|
This software is provided 'as-is', without any express or implied
|
||||||
warranty. In no event will the authors be held liable for any damages
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
@ -504,8 +504,10 @@ class ClassLoaderWrapper
|
||||||
// for .NET to handle.
|
// for .NET to handle.
|
||||||
private TypeWrapper CreateArrayType(string name, TypeWrapper elementTypeWrapper, int dims)
|
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;
|
Type elementType = elementTypeWrapper.TypeAsArrayType;
|
||||||
Debug.Assert(!elementType.IsArray);
|
|
||||||
TypeWrapper wrapper;
|
TypeWrapper wrapper;
|
||||||
lock(types.SyncRoot)
|
lock(types.SyncRoot)
|
||||||
{
|
{
|
||||||
|
@ -809,7 +811,7 @@ class ClassLoaderWrapper
|
||||||
Type[] types = new Type[wrappers.Length];
|
Type[] types = new Type[wrappers.Length];
|
||||||
for(int i = 0; i < wrappers.Length; i++)
|
for(int i = 0; i < wrappers.Length; i++)
|
||||||
{
|
{
|
||||||
types[i] = wrappers[i].TypeAsParameterType;
|
types[i] = wrappers[i].TypeAsSignatureType;
|
||||||
}
|
}
|
||||||
return types;
|
return types;
|
||||||
}
|
}
|
||||||
|
@ -986,11 +988,6 @@ class ClassLoaderWrapper
|
||||||
rank++;
|
rank++;
|
||||||
elem = elem.GetElementType();
|
elem = elem.GetElementType();
|
||||||
}
|
}
|
||||||
// HACK BYTE[]
|
|
||||||
//if(elem == typeof(byte))
|
|
||||||
//{
|
|
||||||
// elem = typeof(sbyte);
|
|
||||||
//}
|
|
||||||
wrapper = GetWrapperFromType(elem);
|
wrapper = GetWrapperFromType(elem);
|
||||||
return wrapper.MakeArrayType(rank);
|
return wrapper.MakeArrayType(rank);
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,13 +79,19 @@ namespace IKVM.Runtime
|
||||||
public unsafe sealed class JNI
|
public unsafe sealed class JNI
|
||||||
{
|
{
|
||||||
internal static bool jvmCreated;
|
internal static bool jvmCreated;
|
||||||
|
internal static bool jvmDestroyed;
|
||||||
internal const string METHOD_PTR_FIELD_PREFIX = "__<jniptr/";
|
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)
|
public static int CreateJavaVM(void* ppvm, void* ppenv, void* args)
|
||||||
{
|
{
|
||||||
JavaVMInitArgs* pInitArgs = (JavaVMInitArgs*)args;
|
JavaVMInitArgs* pInitArgs = (JavaVMInitArgs*)args;
|
||||||
// we don't support the JDK 1.1 JavaVMInitArgs
|
// 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;
|
return JNIEnv.JNI_EVERSION;
|
||||||
}
|
}
|
||||||
|
@ -377,43 +383,11 @@ namespace IKVM.Runtime
|
||||||
[DllImport("ikvm-native")]
|
[DllImport("ikvm-native")]
|
||||||
internal unsafe static extern void* ikvm_MarshalDelegate(Delegate d);
|
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();
|
private static ArrayList nativeLibraries = new ArrayList();
|
||||||
internal static readonly object JniLock = new object();
|
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)
|
lock(JniLock)
|
||||||
{
|
{
|
||||||
IntPtr p = ikvm_LoadLibrary(filename);
|
IntPtr p = ikvm_LoadLibrary(filename);
|
||||||
|
@ -444,7 +418,7 @@ namespace IKVM.Runtime
|
||||||
ClassLoaderWrapper prevLoader = f.Enter(loader);
|
ClassLoaderWrapper prevLoader = f.Enter(loader);
|
||||||
int version = ikvm_CallOnLoad(onload, JavaVM.pJavaVM, null);
|
int version = ikvm_CallOnLoad(onload, JavaVM.pJavaVM, null);
|
||||||
f.Leave(prevLoader);
|
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);
|
throw JavaException.UnsatisfiedLinkError("Unsupported JNI version 0x{0:X} required by {1}", version, filename);
|
||||||
}
|
}
|
||||||
|
@ -922,8 +896,13 @@ namespace IKVM.Runtime
|
||||||
|
|
||||||
internal static jint DestroyJavaVM(JavaVM* pJVM)
|
internal static jint DestroyJavaVM(JavaVM* pJVM)
|
||||||
{
|
{
|
||||||
|
if(JNI.jvmDestroyed)
|
||||||
|
{
|
||||||
|
return JNIEnv.JNI_ERR;
|
||||||
|
}
|
||||||
|
JNI.jvmDestroyed = true;
|
||||||
JVM.Library.jniWaitUntilLastThread();
|
JVM.Library.jniWaitUntilLastThread();
|
||||||
return JNIEnv.JNI_ERR;
|
return JNIEnv.JNI_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static jint AttachCurrentThread(JavaVM* pJVM, void **penv, void *args)
|
internal static jint AttachCurrentThread(JavaVM* pJVM, void **penv, void *args)
|
||||||
|
@ -935,7 +914,7 @@ namespace IKVM.Runtime
|
||||||
{
|
{
|
||||||
if(pAttachArgs != null)
|
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;
|
*penv = null;
|
||||||
return JNIEnv.JNI_EVERSION;
|
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,
|
// 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
|
// 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.
|
// thread we're making are somewhat dubious.
|
||||||
|
System.Threading.Thread.CurrentThread.IsBackground = asDaemon;
|
||||||
if(pAttachArgs != null)
|
if(pAttachArgs != null)
|
||||||
{
|
{
|
||||||
if(pAttachArgs->name != null && System.Threading.Thread.CurrentThread.Name == null)
|
if(pAttachArgs->name != null && System.Threading.Thread.CurrentThread.Name == null)
|
||||||
{
|
{
|
||||||
System.Threading.Thread.CurrentThread.Name = new String(pAttachArgs->name);
|
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
|
// 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);
|
object threadGroup = p->UnwrapRef(pAttachArgs->group);
|
||||||
if(threadGroup != null)
|
if(threadGroup != null)
|
||||||
{
|
{
|
||||||
// TODO instead of using a thread data slot to communicate the thread group, we should probably use
|
JVM.Library.setThreadGroup(threadGroup);
|
||||||
// another mechanism, this is probably a security issue.
|
|
||||||
System.Threading.Thread.SetData(System.Threading.Thread.GetNamedDataSlot("ikvm-thread-group"), threadGroup);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
System.Threading.Thread.CurrentThread.IsBackground = asDaemon;
|
|
||||||
*penv = JNIEnv.CreateJNIEnv();
|
*penv = JNIEnv.CreateJNIEnv();
|
||||||
return JNIEnv.JNI_OK;
|
return JNIEnv.JNI_OK;
|
||||||
}
|
}
|
||||||
|
@ -974,7 +958,8 @@ namespace IKVM.Runtime
|
||||||
{
|
{
|
||||||
if(TlsHack.pJNIEnv == null)
|
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.
|
// 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();
|
JNIEnv.FreeJNIEnv();
|
||||||
|
@ -982,14 +967,9 @@ namespace IKVM.Runtime
|
||||||
return JNIEnv.JNI_OK;
|
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)
|
internal static jint GetEnv(JavaVM* pJVM, void **penv, jint version)
|
||||||
{
|
{
|
||||||
if(IsSupportedJniVersion(version))
|
if(JNI.IsSupportedJniVersion(version))
|
||||||
{
|
{
|
||||||
JNIEnv* p = TlsHack.pJNIEnv;
|
JNIEnv* p = TlsHack.pJNIEnv;
|
||||||
if(p != null)
|
if(p != null)
|
||||||
|
@ -1013,6 +993,8 @@ namespace IKVM.Runtime
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
unsafe struct JNIEnv
|
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_SHIFT = 10;
|
||||||
internal const int LOCAL_REF_BUCKET_SIZE = (1 << LOCAL_REF_SHIFT);
|
internal const int LOCAL_REF_BUCKET_SIZE = (1 << LOCAL_REF_SHIFT);
|
||||||
internal const int LOCAL_REF_MASK = (LOCAL_REF_BUCKET_SIZE - 1);
|
internal const int LOCAL_REF_MASK = (LOCAL_REF_BUCKET_SIZE - 1);
|
||||||
|
@ -1255,23 +1237,38 @@ namespace IKVM.Runtime
|
||||||
return ClassLoaderWrapper.GetSystemClassLoader();
|
return ClassLoaderWrapper.GetSystemClassLoader();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static jclass FindClass(JNIEnv* pEnv, byte* name)
|
internal static jclass FindClass(JNIEnv* pEnv, byte* pszName)
|
||||||
{
|
{
|
||||||
try
|
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();
|
wrapper.Finish();
|
||||||
// spec doesn't say it, but Sun runs the static initializer
|
// spec doesn't say it, but Sun runs the static initializer
|
||||||
wrapper.RunClassInit();
|
wrapper.RunClassInit();
|
||||||
return pEnv->MakeLocalRef(wrapper.ClassObject);
|
return pEnv->MakeLocalRef(wrapper.ClassObject);
|
||||||
}
|
}
|
||||||
catch(RetargetableJavaException x)
|
|
||||||
{
|
|
||||||
SetPendingException(pEnv, x.ToJava());
|
|
||||||
return IntPtr.Zero;
|
|
||||||
}
|
|
||||||
catch(Exception x)
|
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);
|
SetPendingException(pEnv, x);
|
||||||
return IntPtr.Zero;
|
return IntPtr.Zero;
|
||||||
}
|
}
|
||||||
|
@ -1415,8 +1412,15 @@ namespace IKVM.Runtime
|
||||||
localRefs[pEnv->localRefSlot - 1] = null;
|
localRefs[pEnv->localRefSlot - 1] = null;
|
||||||
if(localRefs[pEnv->localRefSlot] == null)
|
if(localRefs[pEnv->localRefSlot] == null)
|
||||||
{
|
{
|
||||||
// we can't use capacity, because the array length must be a power of two
|
// we can't use capacity directly, because the array length must be a power of two
|
||||||
localRefs[pEnv->localRefSlot] = new object[LOCAL_REF_BUCKET_SIZE];
|
// 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;
|
return JNI_OK;
|
||||||
}
|
}
|
||||||
|
@ -1600,7 +1604,7 @@ namespace IKVM.Runtime
|
||||||
}
|
}
|
||||||
catch(Exception x)
|
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;
|
x = x.InnerException;
|
||||||
}
|
}
|
||||||
|
@ -1621,6 +1625,8 @@ namespace IKVM.Runtime
|
||||||
|
|
||||||
internal static jboolean IsInstanceOf(JNIEnv* pEnv, jobject obj, jclass clazz)
|
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));
|
object objClass = IKVM.Runtime.Util.GetClassFromObject(pEnv->UnwrapRef(obj));
|
||||||
TypeWrapper w1 = IKVM.NativeCode.java.lang.VMClass.getWrapperFromClass(pEnv->UnwrapRef(clazz));
|
TypeWrapper w1 = IKVM.NativeCode.java.lang.VMClass.getWrapperFromClass(pEnv->UnwrapRef(clazz));
|
||||||
TypeWrapper w2 = IKVM.NativeCode.java.lang.VMClass.getWrapperFromClass(objClass);
|
TypeWrapper w2 = IKVM.NativeCode.java.lang.VMClass.getWrapperFromClass(objClass);
|
||||||
|
@ -1680,7 +1686,7 @@ namespace IKVM.Runtime
|
||||||
object o = InvokeHelper(pEnv, obj, methodID, args, false);
|
object o = InvokeHelper(pEnv, obj, methodID, args, false);
|
||||||
if(o != null)
|
if(o != null)
|
||||||
{
|
{
|
||||||
return (jbyte)(sbyte)o;
|
return (jbyte)(byte)o;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1770,7 +1776,7 @@ namespace IKVM.Runtime
|
||||||
object o = InvokeHelper(pEnv, obj, methodID, args, true);
|
object o = InvokeHelper(pEnv, obj, methodID, args, true);
|
||||||
if(o != null)
|
if(o != null)
|
||||||
{
|
{
|
||||||
return (jbyte)(sbyte)o;
|
return (jbyte)(byte)o;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1851,7 +1857,6 @@ namespace IKVM.Runtime
|
||||||
{
|
{
|
||||||
if(fw.IsStatic == isstatic)
|
if(fw.IsStatic == isstatic)
|
||||||
{
|
{
|
||||||
// TODO fw.Link()
|
|
||||||
return fw.Cookie;
|
return fw.Cookie;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1911,7 +1916,7 @@ namespace IKVM.Runtime
|
||||||
|
|
||||||
internal static jbyte GetByteField(JNIEnv* pEnv, jobject obj, jfieldID fieldID)
|
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)
|
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)
|
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)
|
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);
|
object o = InvokeHelper(pEnv, IntPtr.Zero, methodID, args, false);
|
||||||
if(o != null)
|
if(o != null)
|
||||||
{
|
{
|
||||||
return (jbyte)(sbyte)o;
|
return (jbyte)(byte)o;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2101,7 +2106,7 @@ namespace IKVM.Runtime
|
||||||
|
|
||||||
internal static jbyte GetStaticByteField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID)
|
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)
|
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)
|
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)
|
internal static void SetStaticCharField(JNIEnv* pEnv, jclass clazz, jfieldID fieldID, jchar val)
|
||||||
|
@ -2328,7 +2333,7 @@ namespace IKVM.Runtime
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return pEnv->MakeLocalRef(new sbyte[len]);
|
return pEnv->MakeLocalRef(new byte[len]);
|
||||||
}
|
}
|
||||||
catch(Exception x)
|
catch(Exception x)
|
||||||
{
|
{
|
||||||
|
@ -2432,7 +2437,7 @@ namespace IKVM.Runtime
|
||||||
|
|
||||||
internal static jbyte* GetByteArrayElements(JNIEnv* pEnv, jbyteArray array, jboolean* isCopy)
|
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);
|
jbyte* p = (jbyte*)(void*)JniMem.Alloc(b.Length * 1);
|
||||||
for(int i = 0; i < b.Length; i++)
|
for(int i = 0; i < b.Length; i++)
|
||||||
{
|
{
|
||||||
|
@ -2537,10 +2542,10 @@ namespace IKVM.Runtime
|
||||||
{
|
{
|
||||||
if(mode == 0 || mode == JNI_COMMIT)
|
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++)
|
for(int i = 0; i < b.Length; i++)
|
||||||
{
|
{
|
||||||
b[i] = (sbyte)elems[i];
|
b[i] = (byte)elems[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(mode == 0 || mode == JNI_ABORT)
|
if(mode == 0 || mode == JNI_ABORT)
|
||||||
|
@ -2648,8 +2653,8 @@ namespace IKVM.Runtime
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
sbyte[] b = (sbyte[])pEnv->UnwrapRef(array);
|
byte[] b = (byte[])pEnv->UnwrapRef(array);
|
||||||
sbyte* p = (sbyte*)(void*)buf;
|
byte* p = (byte*)(void*)buf;
|
||||||
for(int i = 0; i < len; i++)
|
for(int i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
*p++ = b[start + i];
|
*p++ = b[start + i];
|
||||||
|
@ -2760,8 +2765,8 @@ namespace IKVM.Runtime
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
sbyte[] b = (sbyte[])pEnv->UnwrapRef(array);
|
byte[] b = (byte[])pEnv->UnwrapRef(array);
|
||||||
sbyte* p = (sbyte*)(void*)buf;
|
byte* p = (byte*)(void*)buf;
|
||||||
for(int i = 0; i < len; i++)
|
for(int i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
b[start + i] = *p++;
|
b[start + i] = *p++;
|
||||||
|
@ -3023,19 +3028,19 @@ namespace IKVM.Runtime
|
||||||
private static int GetPrimitiveArrayElementSize(Array ar)
|
private static int GetPrimitiveArrayElementSize(Array ar)
|
||||||
{
|
{
|
||||||
Type type = ar.GetType().GetElementType();
|
Type type = ar.GetType().GetElementType();
|
||||||
if(type == typeof(sbyte) || type == typeof(bool))
|
if(type == PrimitiveTypeWrapper.BYTE.TypeAsArrayType || type == PrimitiveTypeWrapper.BOOLEAN.TypeAsArrayType)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else if(type == typeof(short) || type == typeof(char))
|
else if(type == PrimitiveTypeWrapper.SHORT.TypeAsArrayType || type == PrimitiveTypeWrapper.CHAR.TypeAsArrayType)
|
||||||
{
|
{
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
else if(type == typeof(int) || type == typeof(float))
|
else if(type == PrimitiveTypeWrapper.INT.TypeAsArrayType || type == PrimitiveTypeWrapper.FLOAT.TypeAsArrayType)
|
||||||
{
|
{
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
else if(type == typeof(long) || type == typeof(double))
|
else if(type == PrimitiveTypeWrapper.LONG.TypeAsArrayType || type == PrimitiveTypeWrapper.DOUBLE.TypeAsArrayType)
|
||||||
{
|
{
|
||||||
return 8;
|
return 8;
|
||||||
}
|
}
|
||||||
|
@ -3049,6 +3054,7 @@ namespace IKVM.Runtime
|
||||||
internal static IntPtr GetPrimitiveArrayCritical(JNIEnv* pEnv, IntPtr array, IntPtr isCopy)
|
internal static IntPtr GetPrimitiveArrayCritical(JNIEnv* pEnv, IntPtr array, IntPtr isCopy)
|
||||||
{
|
{
|
||||||
Array ar = (Array)pEnv->UnwrapRef(array);
|
Array ar = (Array)pEnv->UnwrapRef(array);
|
||||||
|
// TODO not 64-bit safe (len can overflow)
|
||||||
int len = ar.Length * GetPrimitiveArrayElementSize(ar);
|
int len = ar.Length * GetPrimitiveArrayElementSize(ar);
|
||||||
GCHandle h = GCHandle.Alloc(ar, GCHandleType.Pinned);
|
GCHandle h = GCHandle.Alloc(ar, GCHandleType.Pinned);
|
||||||
try
|
try
|
||||||
|
@ -3078,6 +3084,7 @@ namespace IKVM.Runtime
|
||||||
if(mode == 0 || mode == JNI_COMMIT)
|
if(mode == 0 || mode == JNI_COMMIT)
|
||||||
{
|
{
|
||||||
Array ar = (Array)pEnv->UnwrapRef(array);
|
Array ar = (Array)pEnv->UnwrapRef(array);
|
||||||
|
// TODO not 64-bit safe (len can overflow)
|
||||||
int len = ar.Length * GetPrimitiveArrayElementSize(ar);
|
int len = ar.Length * GetPrimitiveArrayElementSize(ar);
|
||||||
GCHandle h = GCHandle.Alloc(ar, GCHandleType.Pinned);
|
GCHandle h = GCHandle.Alloc(ar, GCHandleType.Pinned);
|
||||||
try
|
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;
|
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
|
This software is provided 'as-is', without any express or implied
|
||||||
warranty. In no event will the authors be held liable for any damages
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
@ -209,7 +209,7 @@ abstract class MethodWrapper : MemberWrapper
|
||||||
{
|
{
|
||||||
if(ghostMethod == null)
|
if(ghostMethod == null)
|
||||||
{
|
{
|
||||||
ghostMethod = DeclaringType.TypeAsParameterType.GetMethod(this.Name, this.GetParametersForDefineMethod());
|
ghostMethod = DeclaringType.TypeAsSignatureType.GetMethod(this.Name, this.GetParametersForDefineMethod());
|
||||||
if(ghostMethod == null)
|
if(ghostMethod == null)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException("Unable to resolve ghost method");
|
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)
|
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);
|
DeclaringType.GhostRefField.SetValue(wrapper, obj);
|
||||||
|
|
||||||
ResolveGhostMethod();
|
ResolveGhostMethod();
|
||||||
|
@ -245,7 +245,7 @@ abstract class MethodWrapper : MemberWrapper
|
||||||
Type[] types = new Type[parameterTypes.Length];
|
Type[] types = new Type[parameterTypes.Length];
|
||||||
for(int i = 0; i < types.Length; i++)
|
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);
|
method = declaringType.TypeAsBaseType.GetMethod(method.Name, types);
|
||||||
}
|
}
|
||||||
|
@ -383,7 +383,7 @@ abstract class MethodWrapper : MemberWrapper
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return ReturnType.TypeAsParameterType;
|
return ReturnType.TypeAsSignatureType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -393,7 +393,7 @@ abstract class MethodWrapper : MemberWrapper
|
||||||
Type[] temp = new Type[wrappers.Length];
|
Type[] temp = new Type[wrappers.Length];
|
||||||
for(int i = 0; i < wrappers.Length; i++)
|
for(int i = 0; i < wrappers.Length; i++)
|
||||||
{
|
{
|
||||||
temp[i] = wrappers[i].TypeAsParameterType;
|
temp[i] = wrappers[i].TypeAsSignatureType;
|
||||||
}
|
}
|
||||||
return temp;
|
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);
|
Invoker invoker = NonvirtualInvokeHelper.GetInvoker(this);
|
||||||
try
|
try
|
||||||
|
@ -683,6 +688,8 @@ abstract class MethodWrapper : MemberWrapper
|
||||||
AssemblyName name = new AssemblyName();
|
AssemblyName name = new AssemblyName();
|
||||||
name.Name = "NonvirtualInvoker";
|
name.Name = "NonvirtualInvoker";
|
||||||
AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly(name, ClassLoaderWrapper.IsSaveDebugImage ? AssemblyBuilderAccess.RunAndSave : AssemblyBuilderAccess.Run);
|
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)
|
if(ClassLoaderWrapper.IsSaveDebugImage)
|
||||||
{
|
{
|
||||||
module = ab.DefineDynamicModule("NonvirtualInvoker", "NonvirtualInvoker.dll");
|
module = ab.DefineDynamicModule("NonvirtualInvoker", "NonvirtualInvoker.dll");
|
||||||
|
@ -747,7 +754,10 @@ abstract class MethodWrapper : MemberWrapper
|
||||||
}
|
}
|
||||||
else if(mw.ReturnType.IsGhost)
|
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)
|
else if(mw.ReturnType.IsPrimitive)
|
||||||
{
|
{
|
||||||
|
@ -780,7 +790,7 @@ abstract class MethodWrapper : MemberWrapper
|
||||||
{
|
{
|
||||||
if(!argTypes[i].IsUnloadable && argTypes[i].IsGhost)
|
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]);
|
argTypes[i].GhostRefField.SetValue(v, args[i + 1]);
|
||||||
args[i + 1] = v;
|
args[i + 1] = v;
|
||||||
}
|
}
|
||||||
|
@ -798,7 +808,7 @@ abstract class MethodWrapper : MemberWrapper
|
||||||
{
|
{
|
||||||
this.args = (object[])args.Clone();
|
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]);
|
argTypes[i].GhostRefField.SetValue(v, args[i]);
|
||||||
this.args[i] = v;
|
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)
|
internal sealed override void EmitCall(ILGenerator ilgen)
|
||||||
{
|
{
|
||||||
AssertLinked();
|
AssertLinked();
|
||||||
PreEmit(ilgen);
|
PreEmit(ilgen);
|
||||||
CallImpl(ilgen);
|
CallImpl(ilgen);
|
||||||
PostEmit(ilgen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void CallImpl(ILGenerator ilgen)
|
protected virtual void CallImpl(ILGenerator ilgen)
|
||||||
|
@ -883,13 +873,13 @@ class SmartMethodWrapper : MethodWrapper
|
||||||
if(DeclaringType.IsNonPrimitiveValueType)
|
if(DeclaringType.IsNonPrimitiveValueType)
|
||||||
{
|
{
|
||||||
// callvirt isn't allowed on a value type
|
// callvirt isn't allowed on a value type
|
||||||
|
// TODO we need to check for a null reference
|
||||||
CallImpl(ilgen);
|
CallImpl(ilgen);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CallvirtImpl(ilgen);
|
CallvirtImpl(ilgen);
|
||||||
}
|
}
|
||||||
PostEmit(ilgen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void CallvirtImpl(ILGenerator ilgen)
|
protected virtual void CallvirtImpl(ILGenerator ilgen)
|
||||||
|
@ -1282,91 +1272,32 @@ sealed class SimpleFieldWrapper : FieldWrapper
|
||||||
|
|
||||||
protected override void EmitGetImpl(ILGenerator ilgen)
|
protected override void EmitGetImpl(ILGenerator ilgen)
|
||||||
{
|
{
|
||||||
if(FieldTypeWrapper.IsGhost)
|
if(!IsStatic && DeclaringType.IsNonPrimitiveValueType)
|
||||||
{
|
{
|
||||||
FieldInfo fi = GetField();
|
ilgen.Emit(OpCodes.Unbox, DeclaringType.TypeAsTBD);
|
||||||
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(IsVolatile)
|
||||||
{
|
{
|
||||||
if(!IsStatic && DeclaringType.IsNonPrimitiveValueType)
|
ilgen.Emit(OpCodes.Volatile);
|
||||||
{
|
|
||||||
ilgen.Emit(OpCodes.Unbox, DeclaringType.TypeAsTBD);
|
|
||||||
}
|
|
||||||
if(IsVolatile)
|
|
||||||
{
|
|
||||||
ilgen.Emit(OpCodes.Volatile);
|
|
||||||
}
|
|
||||||
ilgen.Emit(IsStatic ? OpCodes.Ldsfld : OpCodes.Ldfld, GetField());
|
|
||||||
if(!FieldTypeWrapper.IsUnloadable && FieldTypeWrapper.IsNonPrimitiveValueType)
|
|
||||||
{
|
|
||||||
FieldTypeWrapper.EmitBox(ilgen);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
ilgen.Emit(IsStatic ? OpCodes.Ldsfld : OpCodes.Ldfld, GetField());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void EmitSetImpl(ILGenerator ilgen)
|
protected override void EmitSetImpl(ILGenerator ilgen)
|
||||||
{
|
{
|
||||||
if(FieldTypeWrapper.IsGhost)
|
FieldInfo fi = GetField();
|
||||||
|
if(!IsStatic && DeclaringType.IsNonPrimitiveValueType)
|
||||||
{
|
{
|
||||||
FieldInfo fi = GetField();
|
LocalBuilder temp = ilgen.DeclareLocal(fi.FieldType);
|
||||||
LocalBuilder temp = ilgen.DeclareLocal(FieldTypeWrapper.TypeAsLocalOrStackType);
|
|
||||||
ilgen.Emit(OpCodes.Stloc, temp);
|
ilgen.Emit(OpCodes.Stloc, temp);
|
||||||
if(fi.IsStatic)
|
ilgen.Emit(OpCodes.Unbox, DeclaringType.TypeAsTBD);
|
||||||
{
|
|
||||||
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.Ldloc, temp);
|
||||||
if(IsVolatile)
|
|
||||||
{
|
|
||||||
ilgen.Emit(OpCodes.Volatile);
|
|
||||||
}
|
|
||||||
ilgen.Emit(OpCodes.Stfld, FieldTypeWrapper.GhostRefField);
|
|
||||||
}
|
}
|
||||||
else
|
if(IsVolatile)
|
||||||
{
|
{
|
||||||
if(!IsStatic && DeclaringType.IsNonPrimitiveValueType)
|
ilgen.Emit(OpCodes.Volatile);
|
||||||
{
|
|
||||||
FieldInfo fi = GetField();
|
|
||||||
LocalBuilder temp = ilgen.DeclareLocal(FieldTypeWrapper.TypeAsLocalOrStackType);
|
|
||||||
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)
|
: base(declaringType, fieldType, name, sig, modifiers, fi)
|
||||||
{
|
{
|
||||||
Debug.Assert(IsVolatile);
|
Debug.Assert(IsVolatile);
|
||||||
Debug.Assert(fieldType == PrimitiveTypeWrapper.DOUBLE || fieldType == PrimitiveTypeWrapper.LONG);
|
Debug.Assert(sig == "J" || sig == "D");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void EmitGetImpl(ILGenerator ilgen)
|
protected override void EmitGetImpl(ILGenerator ilgen)
|
||||||
|
@ -1460,88 +1391,30 @@ sealed class GetterFieldWrapper : FieldWrapper
|
||||||
|
|
||||||
protected override void EmitGetImpl(ILGenerator ilgen)
|
protected override void EmitGetImpl(ILGenerator ilgen)
|
||||||
{
|
{
|
||||||
if(IsStatic)
|
if(!IsStatic && DeclaringType.IsNonPrimitiveValueType)
|
||||||
{
|
{
|
||||||
|
ilgen.Emit(OpCodes.Unbox, DeclaringType.TypeAsTBD);
|
||||||
ilgen.Emit(OpCodes.Call, getter);
|
ilgen.Emit(OpCodes.Call, getter);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(DeclaringType.IsNonPrimitiveValueType)
|
// 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(OpCodes.Unbox, DeclaringType.TypeAsTBD);
|
ilgen.Emit(getter.IsStatic ? OpCodes.Call : OpCodes.Callvirt, getter);
|
||||||
ilgen.Emit(OpCodes.Call, getter);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
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)
|
protected override void EmitSetImpl(ILGenerator ilgen)
|
||||||
{
|
{
|
||||||
FieldInfo fi = GetField();
|
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);
|
ilgen.Emit(OpCodes.Stloc, temp);
|
||||||
if(DeclaringType.IsNonPrimitiveValueType)
|
ilgen.Emit(OpCodes.Unbox, DeclaringType.TypeAsTBD);
|
||||||
{
|
|
||||||
ilgen.Emit(OpCodes.Unbox, DeclaringType.TypeAsTBD);
|
|
||||||
}
|
|
||||||
ilgen.Emit(OpCodes.Ldloc, temp);
|
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
ilgen.Emit(IsStatic ? OpCodes.Stsfld : OpCodes.Stfld, fi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1569,6 +1442,8 @@ sealed class ConstantFieldWrapper : FieldWrapper
|
||||||
}
|
}
|
||||||
else if(constant is int ||
|
else if(constant is int ||
|
||||||
constant is short ||
|
constant is short ||
|
||||||
|
constant is ushort ||
|
||||||
|
constant is byte ||
|
||||||
constant is sbyte ||
|
constant is sbyte ||
|
||||||
constant is char ||
|
constant is char ||
|
||||||
constant is bool)
|
constant is bool)
|
||||||
|
@ -1591,25 +1466,13 @@ sealed class ConstantFieldWrapper : FieldWrapper
|
||||||
{
|
{
|
||||||
ilgen.Emit(OpCodes.Ldc_I8, (long)constant);
|
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)
|
else if(constant is uint)
|
||||||
{
|
{
|
||||||
ilgen.Emit(OpCodes.Ldc_I4, unchecked((int)((IConvertible)constant).ToUInt32(null)));
|
ilgen.Emit(OpCodes.Ldc_I4, unchecked((int)((IConvertible)constant).ToUInt32(null)));
|
||||||
ilgen.Emit(OpCodes.Box, typeof(uint));
|
|
||||||
}
|
}
|
||||||
else if(constant is ulong)
|
else if(constant is ulong)
|
||||||
{
|
{
|
||||||
ilgen.Emit(OpCodes.Ldc_I8, unchecked((long)(ulong)constant));
|
ilgen.Emit(OpCodes.Ldc_I8, unchecked((long)(ulong)constant));
|
||||||
ilgen.Emit(OpCodes.Box, typeof(ulong));
|
|
||||||
}
|
}
|
||||||
else if(constant is Enum)
|
else if(constant is Enum)
|
||||||
{
|
{
|
||||||
|
@ -1617,12 +1480,10 @@ sealed class ConstantFieldWrapper : FieldWrapper
|
||||||
if(val is long)
|
if(val is long)
|
||||||
{
|
{
|
||||||
ilgen.Emit(OpCodes.Ldc_I8, (long)constant);
|
ilgen.Emit(OpCodes.Ldc_I8, (long)constant);
|
||||||
ilgen.Emit(OpCodes.Box, constant.GetType());
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ilgen.Emit(OpCodes.Ldc_I4, ((IConvertible)constant).ToInt32(null));
|
ilgen.Emit(OpCodes.Ldc_I4, ((IConvertible)constant).ToInt32(null));
|
||||||
ilgen.Emit(OpCodes.Box, constant.GetType());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
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
|
// 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
|
// 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);
|
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
|
This software is provided 'as-is', without any express or implied
|
||||||
warranty. In no event will the authors be held liable for any damages
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
@ -472,7 +472,7 @@ abstract class TypeWrapper
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.baseWrapper = baseWrapper;
|
this.baseWrapper = baseWrapper;
|
||||||
this.classLoader = classLoader;
|
this.classLoader = classLoader;
|
||||||
if(JVM.IsStaticCompiler)
|
if(IsUnloadable || IsVerifierType || JVM.IsStaticCompiler)
|
||||||
{
|
{
|
||||||
this.classObject = null;
|
this.classObject = null;
|
||||||
}
|
}
|
||||||
|
@ -486,7 +486,7 @@ abstract class TypeWrapper
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
Debug.Assert(!IsUnloadable);
|
Debug.Assert(!IsUnloadable && !IsVerifierType);
|
||||||
return classObject;
|
return classObject;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -902,15 +902,7 @@ abstract class TypeWrapper
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Type TypeAsFieldType
|
internal Type TypeAsSignatureType
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return TypeAsParameterType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal Type TypeAsParameterType
|
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
@ -991,13 +983,7 @@ abstract class TypeWrapper
|
||||||
}
|
}
|
||||||
return Type.GetType(type, true);
|
return Type.GetType(type, true);
|
||||||
}
|
}
|
||||||
Type t = TypeAsTBD;
|
return TypeAsTBD;
|
||||||
// HACK BYTE[]
|
|
||||||
//if(t == typeof(sbyte))
|
|
||||||
//{
|
|
||||||
// return typeof(byte);
|
|
||||||
//}
|
|
||||||
return t;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1337,9 +1323,31 @@ abstract class TypeWrapper
|
||||||
ilgen.Emit(OpCodes.Box, this.TypeAsTBD);
|
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
|
// it is *not* used to automatically downcast
|
||||||
internal void EmitConvStackToParameterType(ILGenerator ilgen, TypeWrapper sourceType)
|
internal void EmitConvStackTypeToSignatureType(ILGenerator ilgen, TypeWrapper sourceType)
|
||||||
{
|
{
|
||||||
if(!IsUnloadable)
|
if(!IsUnloadable)
|
||||||
{
|
{
|
||||||
|
@ -1347,12 +1355,12 @@ abstract class TypeWrapper
|
||||||
{
|
{
|
||||||
LocalBuilder local1 = ilgen.DeclareLocal(TypeAsLocalOrStackType);
|
LocalBuilder local1 = ilgen.DeclareLocal(TypeAsLocalOrStackType);
|
||||||
ilgen.Emit(OpCodes.Stloc, local1);
|
ilgen.Emit(OpCodes.Stloc, local1);
|
||||||
LocalBuilder local2 = ilgen.DeclareLocal(TypeAsParameterType);
|
LocalBuilder local2 = ilgen.DeclareLocal(TypeAsSignatureType);
|
||||||
ilgen.Emit(OpCodes.Ldloca, local2);
|
ilgen.Emit(OpCodes.Ldloca, local2);
|
||||||
ilgen.Emit(OpCodes.Ldloc, local1);
|
ilgen.Emit(OpCodes.Ldloc, local1);
|
||||||
ilgen.Emit(OpCodes.Stfld, GhostRefField);
|
ilgen.Emit(OpCodes.Stfld, GhostRefField);
|
||||||
ilgen.Emit(OpCodes.Ldloca, local2);
|
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
|
// because of the way interface merging works, any reference is valid
|
||||||
// for any interface reference
|
// 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)
|
internal virtual void EmitCheckcast(TypeWrapper context, ILGenerator ilgen)
|
||||||
{
|
{
|
||||||
if(IsGhost)
|
if(IsGhost)
|
||||||
|
@ -1599,7 +1588,7 @@ class UnloadableTypeWrapper : TypeWrapper
|
||||||
|
|
||||||
class PrimitiveTypeWrapper : 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 CHAR = new PrimitiveTypeWrapper(typeof(char), "C");
|
||||||
internal static readonly PrimitiveTypeWrapper DOUBLE = new PrimitiveTypeWrapper(typeof(double), "D");
|
internal static readonly PrimitiveTypeWrapper DOUBLE = new PrimitiveTypeWrapper(typeof(double), "D");
|
||||||
internal static readonly PrimitiveTypeWrapper FLOAT = new PrimitiveTypeWrapper(typeof(float), "F");
|
internal static readonly PrimitiveTypeWrapper FLOAT = new PrimitiveTypeWrapper(typeof(float), "F");
|
||||||
|
@ -1675,6 +1664,11 @@ class PrimitiveTypeWrapper : TypeWrapper
|
||||||
internal override void Finish(bool forDebugSave)
|
internal override void Finish(bool forDebugSave)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return "PrimitiveTypeWrapper[" + sigName + "]";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BakedTypeCleanupHack
|
class BakedTypeCleanupHack
|
||||||
|
@ -2278,6 +2272,8 @@ sealed class DynamicTypeWrapper : TypeWrapper
|
||||||
{
|
{
|
||||||
if(wrapper.IsGhost)
|
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();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
// LAMESPEC the CLI spec says interfaces cannot contain nested types (Part.II, 9.6), but that rule isn't enforced
|
// 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++)
|
for(int i = 0; i < caller.Length; i++)
|
||||||
{
|
{
|
||||||
if(caller[i].TypeAsParameterType == typeof(sbyte[]) && callee[i].TypeAsParameterType == typeof(byte[]))
|
if(!caller[i].IsAssignableTo(callee[i]))
|
||||||
{
|
|
||||||
// special case for byte array cheating...
|
|
||||||
}
|
|
||||||
else if(!caller[i].IsAssignableTo(callee[i]))
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2629,7 +2621,7 @@ sealed class DynamicTypeWrapper : TypeWrapper
|
||||||
ClassFile.Field fld = classFile.Fields[GetFieldIndex(fw)];
|
ClassFile.Field fld = classFile.Fields[GetFieldIndex(fw)];
|
||||||
string fieldName = fld.Name;
|
string fieldName = fld.Name;
|
||||||
TypeWrapper typeWrapper = fw.FieldTypeWrapper;
|
TypeWrapper typeWrapper = fw.FieldTypeWrapper;
|
||||||
Type type = typeWrapper.TypeAsFieldType;
|
Type type = typeWrapper.TypeAsSignatureType;
|
||||||
bool setNameSig = typeWrapper.IsUnloadable || typeWrapper.IsGhostArray;
|
bool setNameSig = typeWrapper.IsUnloadable || typeWrapper.IsGhostArray;
|
||||||
if(setNameSig)
|
if(setNameSig)
|
||||||
{
|
{
|
||||||
|
@ -2905,15 +2897,15 @@ sealed class DynamicTypeWrapper : TypeWrapper
|
||||||
TypeWrapper[] implementers = GetGhostImplementers(wrapper);
|
TypeWrapper[] implementers = GetGhostImplementers(wrapper);
|
||||||
for(int i = 0; i < implementers.Length; i++)
|
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);
|
AttributeHelper.HideFromJava(mb);
|
||||||
ilgen = mb.GetILGenerator();
|
ilgen = mb.GetILGenerator();
|
||||||
local = ilgen.DeclareLocal(wrapper.TypeAsParameterType);
|
local = ilgen.DeclareLocal(wrapper.TypeAsSignatureType);
|
||||||
ilgen.Emit(OpCodes.Ldloca, local);
|
ilgen.Emit(OpCodes.Ldloca, local);
|
||||||
ilgen.Emit(OpCodes.Ldarg_0);
|
ilgen.Emit(OpCodes.Ldarg_0);
|
||||||
ilgen.Emit(OpCodes.Stfld, wrapper.GhostRefField);
|
ilgen.Emit(OpCodes.Stfld, wrapper.GhostRefField);
|
||||||
ilgen.Emit(OpCodes.Ldloca, local);
|
ilgen.Emit(OpCodes.Ldloca, local);
|
||||||
ilgen.Emit(OpCodes.Ldobj, wrapper.TypeAsParameterType);
|
ilgen.Emit(OpCodes.Ldobj, wrapper.TypeAsSignatureType);
|
||||||
ilgen.Emit(OpCodes.Ret);
|
ilgen.Emit(OpCodes.Ret);
|
||||||
}
|
}
|
||||||
// Implement the "IsInstance" method
|
// Implement the "IsInstance" method
|
||||||
|
@ -3005,12 +2997,12 @@ sealed class DynamicTypeWrapper : TypeWrapper
|
||||||
ilgen.Emit(OpCodes.Castclass, wrapper.TypeAsBaseType);
|
ilgen.Emit(OpCodes.Castclass, wrapper.TypeAsBaseType);
|
||||||
ilgen.Emit(OpCodes.Pop);
|
ilgen.Emit(OpCodes.Pop);
|
||||||
ilgen.MarkLabel(end);
|
ilgen.MarkLabel(end);
|
||||||
local = ilgen.DeclareLocal(wrapper.TypeAsParameterType);
|
local = ilgen.DeclareLocal(wrapper.TypeAsSignatureType);
|
||||||
ilgen.Emit(OpCodes.Ldloca, local);
|
ilgen.Emit(OpCodes.Ldloca, local);
|
||||||
ilgen.Emit(OpCodes.Ldarg_0);
|
ilgen.Emit(OpCodes.Ldarg_0);
|
||||||
ilgen.Emit(OpCodes.Stfld, wrapper.ghostRefField);
|
ilgen.Emit(OpCodes.Stfld, wrapper.ghostRefField);
|
||||||
ilgen.Emit(OpCodes.Ldloca, local);
|
ilgen.Emit(OpCodes.Ldloca, local);
|
||||||
ilgen.Emit(OpCodes.Ldobj, wrapper.TypeAsParameterType);
|
ilgen.Emit(OpCodes.Ldobj, wrapper.TypeAsSignatureType);
|
||||||
ilgen.Emit(OpCodes.Ret);
|
ilgen.Emit(OpCodes.Ret);
|
||||||
// Add "ToObject" methods
|
// Add "ToObject" methods
|
||||||
mb = typeBuilder.DefineMethod("ToObject", MethodAttributes.Public, typeof(object), Type.EmptyTypes);
|
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
|
// TODO do this for indirectly implemented interfaces (interfaces implemented by interfaces) as well
|
||||||
if(interfaces[i].IsGhost)
|
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);
|
AttributeHelper.HideFromJava(mb);
|
||||||
ILGenerator ilgen = mb.GetILGenerator();
|
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.Ldloca, local);
|
||||||
ilgen.Emit(OpCodes.Ldarg_0);
|
ilgen.Emit(OpCodes.Ldarg_0);
|
||||||
ilgen.Emit(OpCodes.Stfld, interfaces[i].GhostRefField);
|
ilgen.Emit(OpCodes.Stfld, interfaces[i].GhostRefField);
|
||||||
ilgen.Emit(OpCodes.Ldloca, local);
|
ilgen.Emit(OpCodes.Ldloca, local);
|
||||||
ilgen.Emit(OpCodes.Ldobj, interfaces[i].TypeAsParameterType);
|
ilgen.Emit(OpCodes.Ldobj, interfaces[i].TypeAsSignatureType);
|
||||||
ilgen.Emit(OpCodes.Ret);
|
ilgen.Emit(OpCodes.Ret);
|
||||||
}
|
}
|
||||||
interfaces[i].ImplementInterfaceMethodStubs(typeBuilder, wrapper, doneSet);
|
interfaces[i].ImplementInterfaceMethodStubs(typeBuilder, wrapper, doneSet);
|
||||||
|
@ -3321,13 +3313,13 @@ sealed class DynamicTypeWrapper : TypeWrapper
|
||||||
if(f.ConstantValue != null)
|
if(f.ConstantValue != null)
|
||||||
{
|
{
|
||||||
FieldAttributes attribs = FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal;
|
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);
|
fb.SetConstant(f.ConstantValue);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FieldAttributes attribs = FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.InitOnly;
|
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)
|
if(ilgenClinit == null)
|
||||||
{
|
{
|
||||||
ilgenClinit = tbFields.DefineTypeInitializer().GetILGenerator();
|
ilgenClinit = tbFields.DefineTypeInitializer().GetILGenerator();
|
||||||
|
@ -3406,14 +3398,14 @@ sealed class DynamicTypeWrapper : TypeWrapper
|
||||||
Type[] argTypes = new Type[args.Length + instance + 1];
|
Type[] argTypes = new Type[args.Length + instance + 1];
|
||||||
if(instance != 0)
|
if(instance != 0)
|
||||||
{
|
{
|
||||||
argTypes[0] = wrapper.TypeAsParameterType;
|
argTypes[0] = wrapper.TypeAsSignatureType;
|
||||||
}
|
}
|
||||||
for(int i = 0; i < args.Length; i++)
|
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);
|
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);
|
JniBuilder.Generate(mb.GetILGenerator(), wrapper, mw, tb, classFile, m, args, true);
|
||||||
for(int i = 0; i < argTypes.Length - 1; i++)
|
for(int i = 0; i < argTypes.Length - 1; i++)
|
||||||
{
|
{
|
||||||
|
@ -3507,7 +3499,7 @@ sealed class DynamicTypeWrapper : TypeWrapper
|
||||||
ilGenerator.Emit(OpCodes.Stloc, jnienv);
|
ilGenerator.Emit(OpCodes.Stloc, jnienv);
|
||||||
Label tryBlock = ilGenerator.BeginExceptionBlock();
|
Label tryBlock = ilGenerator.BeginExceptionBlock();
|
||||||
TypeWrapper retTypeWrapper = mw.ReturnType;
|
TypeWrapper retTypeWrapper = mw.ReturnType;
|
||||||
if(!retTypeWrapper.IsPrimitive)
|
if(!retTypeWrapper.IsUnloadable && !retTypeWrapper.IsPrimitive)
|
||||||
{
|
{
|
||||||
// this one is for use after we return from "calli"
|
// this one is for use after we return from "calli"
|
||||||
ilGenerator.Emit(OpCodes.Ldloca, localRefStruct);
|
ilGenerator.Emit(OpCodes.Ldloca, localRefStruct);
|
||||||
|
@ -3518,7 +3510,7 @@ sealed class DynamicTypeWrapper : TypeWrapper
|
||||||
modargs[1] = typeof(IntPtr);
|
modargs[1] = typeof(IntPtr);
|
||||||
for(int i = 0; i < args.Length; i++)
|
for(int i = 0; i < args.Length; i++)
|
||||||
{
|
{
|
||||||
modargs[i + 2] = args[i].TypeAsParameterType;
|
modargs[i + 2] = args[i].TypeAsSignatureType;
|
||||||
}
|
}
|
||||||
int add = 0;
|
int add = 0;
|
||||||
if(!m.IsStatic)
|
if(!m.IsStatic)
|
||||||
|
@ -3548,11 +3540,20 @@ sealed class DynamicTypeWrapper : TypeWrapper
|
||||||
if(!args[j].IsPrimitive)
|
if(!args[j].IsPrimitive)
|
||||||
{
|
{
|
||||||
ilGenerator.Emit(OpCodes.Ldloca, localRefStruct);
|
ilGenerator.Emit(OpCodes.Ldloca, localRefStruct);
|
||||||
ilGenerator.Emit(OpCodes.Ldarg_S, (byte)(j + add));
|
|
||||||
if(args[j].IsNonPrimitiveValueType)
|
if(args[j].IsNonPrimitiveValueType)
|
||||||
{
|
{
|
||||||
|
ilGenerator.Emit(OpCodes.Ldarg_S, (byte)(j + add));
|
||||||
args[j].EmitBox(ilGenerator);
|
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);
|
ilGenerator.Emit(OpCodes.Call, makeLocalRef);
|
||||||
modargs[j + 2] = typeof(IntPtr);
|
modargs[j + 2] = typeof(IntPtr);
|
||||||
}
|
}
|
||||||
|
@ -3562,7 +3563,7 @@ sealed class DynamicTypeWrapper : TypeWrapper
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ilGenerator.Emit(OpCodes.Ldsfld, methodPtr);
|
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;
|
LocalBuilder retValue = null;
|
||||||
if(retTypeWrapper != PrimitiveTypeWrapper.VOID)
|
if(retTypeWrapper != PrimitiveTypeWrapper.VOID)
|
||||||
{
|
{
|
||||||
|
@ -3573,12 +3574,22 @@ sealed class DynamicTypeWrapper : TypeWrapper
|
||||||
{
|
{
|
||||||
retTypeWrapper.EmitUnbox(ilGenerator);
|
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);
|
ilGenerator.Emit(OpCodes.Castclass, retTypeWrapper.TypeAsTBD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
retValue = ilGenerator.DeclareLocal(retTypeWrapper.TypeAsParameterType);
|
retValue = ilGenerator.DeclareLocal(retTypeWrapper.TypeAsSignatureType);
|
||||||
ilGenerator.Emit(OpCodes.Stloc, retValue);
|
ilGenerator.Emit(OpCodes.Stloc, retValue);
|
||||||
}
|
}
|
||||||
ilGenerator.BeginCatchBlock(typeof(object));
|
ilGenerator.BeginCatchBlock(typeof(object));
|
||||||
|
@ -5069,7 +5080,7 @@ sealed class DotNetTypeWrapper : TypeWrapper
|
||||||
{
|
{
|
||||||
modifiers |= Modifiers.Final;
|
modifiers |= Modifiers.Final;
|
||||||
}
|
}
|
||||||
if(type.IsAbstract)
|
else if(type.IsAbstract) // we can't be abstract if we're final
|
||||||
{
|
{
|
||||||
modifiers |= Modifiers.Abstract;
|
modifiers |= Modifiers.Abstract;
|
||||||
}
|
}
|
||||||
|
@ -5374,8 +5385,9 @@ sealed class DotNetTypeWrapper : TypeWrapper
|
||||||
|
|
||||||
internal override void EmitCall(ILGenerator ilgen)
|
internal override void EmitCall(ILGenerator ilgen)
|
||||||
{
|
{
|
||||||
// NOTE we don't support custom boxing rules for enums
|
// We don't actually need to do anything here!
|
||||||
ilgen.Emit(OpCodes.Box, ((DotNetTypeWrapper)DeclaringType).type);
|
// 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)
|
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
|
// 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)
|
internal static object GetEnumPrimitiveValue(object obj)
|
||||||
{
|
{
|
||||||
Type underlyingType = Enum.GetUnderlyingType(obj.GetType());
|
Type underlyingType = Enum.GetUnderlyingType(obj.GetType());
|
||||||
if(underlyingType == typeof(sbyte) || underlyingType == typeof(byte))
|
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))
|
else if(underlyingType == typeof(short) || underlyingType == typeof(ushort))
|
||||||
{
|
{
|
||||||
|
@ -5512,9 +5524,9 @@ sealed class DotNetTypeWrapper : TypeWrapper
|
||||||
if(type.IsEnum)
|
if(type.IsEnum)
|
||||||
{
|
{
|
||||||
Type underlyingType = Enum.GetUnderlyingType(type);
|
Type underlyingType = Enum.GetUnderlyingType(type);
|
||||||
if(underlyingType == typeof(byte))
|
if(underlyingType == typeof(sbyte))
|
||||||
{
|
{
|
||||||
underlyingType = typeof(sbyte);
|
underlyingType = typeof(byte);
|
||||||
}
|
}
|
||||||
else if(underlyingType == typeof(ushort))
|
else if(underlyingType == typeof(ushort))
|
||||||
{
|
{
|
||||||
|
@ -5631,6 +5643,7 @@ sealed class DotNetTypeWrapper : TypeWrapper
|
||||||
// (otherwise the type appears abstract while it isn't)
|
// (otherwise the type appears abstract while it isn't)
|
||||||
if(!type.IsAbstract)
|
if(!type.IsAbstract)
|
||||||
{
|
{
|
||||||
|
Hashtable clash = null;
|
||||||
Type[] interfaces = type.GetInterfaces();
|
Type[] interfaces = type.GetInterfaces();
|
||||||
for(int i = 0; i < interfaces.Length; i++)
|
for(int i = 0; i < interfaces.Length; i++)
|
||||||
{
|
{
|
||||||
|
@ -5653,8 +5666,19 @@ sealed class DotNetTypeWrapper : TypeWrapper
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO handle name/signature clash
|
if(clash == null)
|
||||||
methodsList.Add(CreateMethodWrapper(name, sig, map.InterfaceMethods[j], true));
|
{
|
||||||
|
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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -418,7 +418,7 @@ namespace IKVM.Attributes
|
||||||
this.val = val;
|
this.val = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConstantValueAttribute(sbyte val)
|
public ConstantValueAttribute(byte val)
|
||||||
{
|
{
|
||||||
this.val = val;
|
this.val = val;
|
||||||
}
|
}
|
||||||
|
|
|
@ -164,6 +164,13 @@ namespace IKVM.NativeCode.java
|
||||||
throw JavaException.IllegalArgumentException("primitive wrapper null");
|
throw JavaException.IllegalArgumentException("primitive wrapper null");
|
||||||
}
|
}
|
||||||
argsCopy[i] = JVM.Library.unbox(args[i]);
|
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -221,16 +228,6 @@ namespace IKVM.NativeCode.java
|
||||||
return VMClass.getWrapperFromClass(a).IsInSamePackageAs(VMClass.getWrapperFromClass(b));
|
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)
|
public static object GetValue(object fieldCookie, object o)
|
||||||
{
|
{
|
||||||
Profiler.Enter("Field.GetValue");
|
Profiler.Enter("Field.GetValue");
|
||||||
|
@ -272,6 +269,13 @@ namespace IKVM.NativeCode.java
|
||||||
if(wrapper.FieldTypeWrapper.IsPrimitive)
|
if(wrapper.FieldTypeWrapper.IsPrimitive)
|
||||||
{
|
{
|
||||||
v = JVM.Library.unbox(v);
|
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>,
|
// if the field is an interface field, we must explicitly run <clinit>,
|
||||||
// because .NET reflection doesn't
|
// because .NET reflection doesn't
|
||||||
|
@ -291,9 +295,9 @@ namespace IKVM.NativeCode.java
|
||||||
|
|
||||||
public class VMRuntime
|
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 class VMSystem
|
||||||
{
|
{
|
||||||
public static void arraycopy(object src, int srcStart, object dest, int destStart, int len)
|
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");
|
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
|
public class VMClass
|
||||||
|
@ -1162,7 +1138,7 @@ namespace IKVM.NativeCode.java
|
||||||
GetFieldWrapperFromField(field).SetValue(obj, val);
|
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);
|
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
|
// 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
|
// version for now, don't know what the security implications of this are
|
||||||
// SECURITY
|
// 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)
|
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 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()
|
public static string getLocalHostname()
|
||||||
|
@ -1234,23 +1224,17 @@ namespace IKVM.NativeCode.java
|
||||||
return NetSystem.Net.Dns.GetHostName();
|
return NetSystem.Net.Dns.GetHostName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static sbyte[][] getHostByName(string name)
|
public static byte[][] getHostByName(string name)
|
||||||
{
|
{
|
||||||
// TODO error handling
|
// TODO error handling
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
NetSystem.Net.IPHostEntry he = NetSystem.Net.Dns.GetHostByName(name);
|
NetSystem.Net.IPHostEntry he = NetSystem.Net.Dns.GetHostByName(name);
|
||||||
NetSystem.Net.IPAddress[] addresses = he.AddressList;
|
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++)
|
for(int i = 0; i < addresses.Length; i++)
|
||||||
{
|
{
|
||||||
byte[] address = addresses[i].GetAddressBytes();
|
list[i] = 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;
|
|
||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
@ -1392,6 +1376,31 @@ namespace IKVM.NativeCode.gnu.classpath
|
||||||
return typeof(VMSystemProperties).Assembly.GetName().Version.ToString();
|
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
|
namespace gnu.classpath
|
||||||
|
@ -1401,11 +1410,11 @@ namespace gnu.classpath
|
||||||
public unsafe sealed class RawData
|
public unsafe sealed class RawData
|
||||||
{
|
{
|
||||||
[HideFromJava]
|
[HideFromJava]
|
||||||
private sbyte* pb;
|
private byte* pb;
|
||||||
|
|
||||||
public RawData(IntPtr p)
|
public RawData(IntPtr p)
|
||||||
{
|
{
|
||||||
this.pb = (sbyte*)p;
|
this.pb = (byte*)p;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IntPtr 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
|
// security attribute isn't really needed, but to be extra safe we add the explicit link
|
||||||
// demand to these dangerous methods.
|
// demand to these dangerous methods.
|
||||||
[SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true)]
|
[SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true)]
|
||||||
public sbyte ReadByte(int index)
|
public byte ReadByte(int index)
|
||||||
{
|
{
|
||||||
return pb[index];
|
return pb[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
[SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true)]
|
[SecurityPermission(SecurityAction.LinkDemand, Unrestricted = true)]
|
||||||
public void WriteByte(int index, sbyte b)
|
public void WriteByte(int index, byte b)
|
||||||
{
|
{
|
||||||
pb[index] = b;
|
pb[index] = b;
|
||||||
}
|
}
|
||||||
|
@ -1467,6 +1476,7 @@ namespace ikvm.@internal
|
||||||
|
|
||||||
void jniWaitUntilLastThread();
|
void jniWaitUntilLastThread();
|
||||||
void jniDetach();
|
void jniDetach();
|
||||||
|
void setThreadGroup(object group);
|
||||||
|
|
||||||
object newConstructor(object clazz, object wrapper);
|
object newConstructor(object clazz, object wrapper);
|
||||||
object newMethod(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
|
This software is provided 'as-is', without any express or implied
|
||||||
warranty. In no event will the authors be held liable for any damages
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
@ -175,8 +175,9 @@ class Compiler
|
||||||
{
|
{
|
||||||
tw = args[arg - 1];
|
tw = args[arg - 1];
|
||||||
}
|
}
|
||||||
if(v.type != VerifierTypeWrapper.UninitializedThis &&
|
if(!tw.IsUnloadable &&
|
||||||
(v.type != tw || tw.TypeAsLocalOrStackType != tw.TypeAsParameterType))
|
v.type != VerifierTypeWrapper.UninitializedThis &&
|
||||||
|
(v.type != tw || tw.TypeAsLocalOrStackType != tw.TypeAsSignatureType))
|
||||||
{
|
{
|
||||||
v.builder = ilGenerator.DeclareLocal(v.type.TypeAsLocalOrStackType);
|
v.builder = ilGenerator.DeclareLocal(v.type.TypeAsLocalOrStackType);
|
||||||
if(JVM.Debug && v.name != null)
|
if(JVM.Debug && v.name != null)
|
||||||
|
@ -185,7 +186,7 @@ class Compiler
|
||||||
}
|
}
|
||||||
v.isArg = false;
|
v.isArg = false;
|
||||||
ilGenerator.Emit(OpCodes.Ldarg_S, (byte)arg);
|
ilGenerator.Emit(OpCodes.Ldarg_S, (byte)arg);
|
||||||
v.type.EmitConvParameterToStackType(ilGenerator);
|
tw.EmitConvSignatureTypeToStackType(ilGenerator);
|
||||||
ilGenerator.Emit(OpCodes.Stloc, v.builder);
|
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
|
// we must emit code to cast the stack value to the interface type
|
||||||
CastInterfaceArgs(method, cpi.GetArgTypes(), i, false, false);
|
CastInterfaceArgs(method, cpi.GetArgTypes(), i, false, false);
|
||||||
method.EmitCall(ilGenerator);
|
method.EmitCall(ilGenerator);
|
||||||
|
method.ReturnType.EmitConvSignatureTypeToStackType(ilGenerator);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NormalizedByteCode.__invokevirtual:
|
case NormalizedByteCode.__invokevirtual:
|
||||||
|
@ -1614,6 +1616,7 @@ class Compiler
|
||||||
{
|
{
|
||||||
method.EmitCallvirt(ilGenerator);
|
method.EmitCallvirt(ilGenerator);
|
||||||
}
|
}
|
||||||
|
method.ReturnType.EmitConvSignatureTypeToStackType(ilGenerator);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1631,12 +1634,12 @@ class Compiler
|
||||||
if(instr.NormalizedOpCode != NormalizedByteCode.__return)
|
if(instr.NormalizedOpCode != NormalizedByteCode.__return)
|
||||||
{
|
{
|
||||||
TypeWrapper retTypeWrapper = mw.ReturnType;
|
TypeWrapper retTypeWrapper = mw.ReturnType;
|
||||||
retTypeWrapper.EmitConvStackToParameterType(ilGenerator, ma.GetRawStackTypeWrapper(i, 0));
|
retTypeWrapper.EmitConvStackTypeToSignatureType(ilGenerator, ma.GetRawStackTypeWrapper(i, 0));
|
||||||
if(ma.GetRawStackTypeWrapper(i, 0).IsUnloadable)
|
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);
|
ilGenerator.Emit(OpCodes.Stloc, local);
|
||||||
}
|
}
|
||||||
Label label = ilGenerator.DefineLabel();
|
Label label = ilGenerator.DefineLabel();
|
||||||
|
@ -1660,14 +1663,14 @@ class Compiler
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TypeWrapper retTypeWrapper = mw.ReturnType;
|
TypeWrapper retTypeWrapper = mw.ReturnType;
|
||||||
retTypeWrapper.EmitConvStackToParameterType(ilGenerator, ma.GetRawStackTypeWrapper(i, 0));
|
retTypeWrapper.EmitConvStackTypeToSignatureType(ilGenerator, ma.GetRawStackTypeWrapper(i, 0));
|
||||||
if(ma.GetRawStackTypeWrapper(i, 0).IsUnloadable)
|
if(ma.GetRawStackTypeWrapper(i, 0).IsUnloadable)
|
||||||
{
|
{
|
||||||
ilGenerator.Emit(OpCodes.Castclass, retTypeWrapper.TypeAsParameterType);
|
ilGenerator.Emit(OpCodes.Castclass, retTypeWrapper.TypeAsSignatureType);
|
||||||
}
|
}
|
||||||
if(stackHeight != 1)
|
if(stackHeight != 1)
|
||||||
{
|
{
|
||||||
LocalBuilder local = ilGenerator.DeclareLocal(retTypeWrapper.TypeAsParameterType);
|
LocalBuilder local = ilGenerator.DeclareLocal(retTypeWrapper.TypeAsSignatureType);
|
||||||
ilGenerator.Emit(OpCodes.Stloc, local);
|
ilGenerator.Emit(OpCodes.Stloc, local);
|
||||||
ilGenerator.Emit(OpCodes.Leave_S, (byte)0);
|
ilGenerator.Emit(OpCodes.Leave_S, (byte)0);
|
||||||
ilGenerator.Emit(OpCodes.Ldloc, local);
|
ilGenerator.Emit(OpCodes.Ldloc, local);
|
||||||
|
@ -2809,7 +2812,7 @@ class Compiler
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LocalBuilder local = ilGenerator.DeclareLocal(args[i].TypeAsParameterType);
|
LocalBuilder local = ilGenerator.DeclareLocal(args[i].TypeAsSignatureType);
|
||||||
ilGenerator.Emit(OpCodes.Ldloca, local);
|
ilGenerator.Emit(OpCodes.Ldloca, local);
|
||||||
dh.Load(i);
|
dh.Load(i);
|
||||||
ilGenerator.Emit(OpCodes.Stfld, args[i].GhostRefField);
|
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
|
// NOTE when the this argument is a value type, we need the address on the stack instead of the value
|
||||||
if(i != 0 || !instanceMethod)
|
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)
|
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)
|
if(!write)
|
||||||
{
|
{
|
||||||
field.EmitGet(ilGenerator);
|
field.EmitGet(ilGenerator);
|
||||||
|
field.FieldTypeWrapper.EmitConvSignatureTypeToStackType(ilGenerator);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TypeWrapper tw = field.FieldTypeWrapper;
|
TypeWrapper tw = field.FieldTypeWrapper;
|
||||||
TypeWrapper val = ma.GetRawStackTypeWrapper(i, 0);
|
TypeWrapper val = ma.GetRawStackTypeWrapper(i, 0);
|
||||||
if(!tw.IsUnloadable && (val.IsUnloadable || (tw.IsInterfaceOrInterfaceArray && !tw.IsGhost && !val.IsAssignableTo(tw))))
|
tw.EmitConvStackTypeToSignatureType(ilGenerator, val);
|
||||||
{
|
|
||||||
ilGenerator.Emit(OpCodes.Castclass, tw.TypeAsTBD);
|
|
||||||
}
|
|
||||||
field.EmitSet(ilGenerator);
|
field.EmitSet(ilGenerator);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2972,6 +2973,10 @@ class Compiler
|
||||||
// NOTE we don't need to use TypeWrapper.EmitUnbox, because the return value cannot be null
|
// 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.Unbox, typeWrapper.TypeAsTBD);
|
||||||
ilgen.Emit(OpCodes.Ldobj, typeWrapper.TypeAsTBD);
|
ilgen.Emit(OpCodes.Ldobj, typeWrapper.TypeAsTBD);
|
||||||
|
if(typeWrapper == PrimitiveTypeWrapper.BYTE)
|
||||||
|
{
|
||||||
|
ilgen.Emit(OpCodes.Conv_I1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2989,7 +2994,7 @@ class Compiler
|
||||||
private ClassFile.ConstantPoolItemMI cpi;
|
private ClassFile.ConstantPoolItemMI cpi;
|
||||||
|
|
||||||
internal DynamicMethodWrapper(ClassLoaderWrapper classLoader, TypeWrapper wrapper, 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.classLoader = classLoader;
|
||||||
this.wrapper = wrapper;
|
this.wrapper = wrapper;
|
||||||
|
|
|
@ -145,9 +145,9 @@ namespace IKVM.Internal.MapXml
|
||||||
}
|
}
|
||||||
if(tw.IsGhost)
|
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]);
|
ilgen.Emit(OpCodes.Stloc, temps[j]);
|
||||||
}
|
}
|
||||||
for(int j = 0; j < temps.Length; 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);
|
FieldWrapper fw = ClassLoaderWrapper.LoadClassCritical(Class).GetFieldWrapper(Name, Sig);
|
||||||
fw.Link();
|
fw.Link();
|
||||||
// we don't use fw.EmitGet because we don't want automatic boxing and whatever
|
fw.EmitGet(ilgen);
|
||||||
ilgen.Emit(OpCodes.Ldfld, fw.GetField());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ using System.Collections;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Text;
|
||||||
using IKVM.Attributes;
|
using IKVM.Attributes;
|
||||||
using IKVM.Runtime;
|
using IKVM.Runtime;
|
||||||
|
|
||||||
|
@ -99,7 +100,7 @@ namespace IKVM.Runtime
|
||||||
{
|
{
|
||||||
ArrayList list = new ArrayList();
|
ArrayList list = new ArrayList();
|
||||||
string cmdline = Environment.CommandLine;
|
string cmdline = Environment.CommandLine;
|
||||||
System.Text.StringBuilder sb = new System.Text.StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
for(int i = 0; i < cmdline.Length;)
|
for(int i = 0; i < cmdline.Length;)
|
||||||
{
|
{
|
||||||
bool quoted = cmdline[i] == '"';
|
bool quoted = cmdline[i] == '"';
|
||||||
|
@ -406,7 +407,7 @@ namespace IKVM.Internal
|
||||||
// but in order for ILDASM/ILASM round tripping to work reliably, we have
|
// 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 make sure that we don't produce resource names that'll cause ILDASM
|
||||||
// to generate invalid filenames.
|
// 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)
|
foreach(char c in name)
|
||||||
{
|
{
|
||||||
if("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-+.()$#@~=&{}[]0123456789`".IndexOf(c) != -1)
|
if("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-+.()$#@~=&{}[]0123456789`".IndexOf(c) != -1)
|
||||||
|
@ -1121,7 +1122,7 @@ namespace IKVM.Internal
|
||||||
typeWrapper.helperTypeBuilder = typeWrapper.typeBuilder.DefineNestedType("__Helper", TypeAttributes.NestedPublic | TypeAttributes.Class);
|
typeWrapper.helperTypeBuilder = typeWrapper.typeBuilder.DefineNestedType("__Helper", TypeAttributes.NestedPublic | TypeAttributes.Class);
|
||||||
AttributeHelper.HideFromJava(typeWrapper.helperTypeBuilder);
|
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();
|
ILGenerator ilgen = helper.GetILGenerator();
|
||||||
foreach(IKVM.Internal.MapXml.Class c in specialCases)
|
foreach(IKVM.Internal.MapXml.Class c in specialCases)
|
||||||
{
|
{
|
||||||
|
@ -1156,7 +1157,7 @@ namespace IKVM.Internal
|
||||||
{
|
{
|
||||||
MethodBuilder mbCore = null;
|
MethodBuilder mbCore = null;
|
||||||
Type[] paramTypes = typeWrapper.GetClassLoader().ArgTypeListFromSig(m.Sig);
|
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)
|
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)
|
if(instr is IKVM.Internal.MapXml.Ret)
|
||||||
{
|
{
|
||||||
this.ReturnType.EmitConvStackToParameterType(ilgen, null);
|
this.ReturnType.EmitConvStackTypeToSignatureType(ilgen, null);
|
||||||
}
|
}
|
||||||
instr.Generate(context, ilgen);
|
instr.Generate(context, ilgen);
|
||||||
}
|
}
|
||||||
|
@ -1309,7 +1310,7 @@ namespace IKVM.Internal
|
||||||
}
|
}
|
||||||
ilgen.Emit(OpCodes.Call, baseMethod);
|
ilgen.Emit(OpCodes.Call, baseMethod);
|
||||||
}
|
}
|
||||||
this.ReturnType.EmitConvStackToParameterType(ilgen, null);
|
this.ReturnType.EmitConvStackTypeToSignatureType(ilgen, null);
|
||||||
ilgen.Emit(OpCodes.Ret);
|
ilgen.Emit(OpCodes.Ret);
|
||||||
}
|
}
|
||||||
ilgen.EmitLineNumberTable(mbCore);
|
ilgen.EmitLineNumberTable(mbCore);
|
||||||
|
@ -1344,7 +1345,7 @@ namespace IKVM.Internal
|
||||||
ilgen.Emit(OpCodes.Ldarg, (short)(i + 1));
|
ilgen.Emit(OpCodes.Ldarg, (short)(i + 1));
|
||||||
}
|
}
|
||||||
ilgen.Emit(OpCodes.Callvirt, mbCore);
|
ilgen.Emit(OpCodes.Callvirt, mbCore);
|
||||||
this.ReturnType.EmitConvStackToParameterType(ilgen, null);
|
this.ReturnType.EmitConvStackTypeToSignatureType(ilgen, null);
|
||||||
ilgen.Emit(OpCodes.Ret);
|
ilgen.Emit(OpCodes.Ret);
|
||||||
ilgen.MarkLabel(skip);
|
ilgen.MarkLabel(skip);
|
||||||
ilgen.Emit(OpCodes.Pop);
|
ilgen.Emit(OpCodes.Pop);
|
||||||
|
@ -1370,7 +1371,7 @@ namespace IKVM.Internal
|
||||||
}
|
}
|
||||||
mw.Link();
|
mw.Link();
|
||||||
mw.EmitCallvirt(ilgen);
|
mw.EmitCallvirt(ilgen);
|
||||||
this.ReturnType.EmitConvStackToParameterType(ilgen, null);
|
this.ReturnType.EmitConvStackTypeToSignatureType(ilgen, null);
|
||||||
ilgen.Emit(OpCodes.Ret);
|
ilgen.Emit(OpCodes.Ret);
|
||||||
ilgen.MarkLabel(skip);
|
ilgen.MarkLabel(skip);
|
||||||
ilgen.Emit(OpCodes.Pop);
|
ilgen.Emit(OpCodes.Pop);
|
||||||
|
@ -1385,7 +1386,7 @@ namespace IKVM.Internal
|
||||||
{
|
{
|
||||||
if(instr is IKVM.Internal.MapXml.Ret)
|
if(instr is IKVM.Internal.MapXml.Ret)
|
||||||
{
|
{
|
||||||
this.ReturnType.EmitConvStackToParameterType(ilgen, null);
|
this.ReturnType.EmitConvStackTypeToSignatureType(ilgen, null);
|
||||||
}
|
}
|
||||||
instr.Generate(context, ilgen);
|
instr.Generate(context, ilgen);
|
||||||
}
|
}
|
||||||
|
@ -1428,7 +1429,7 @@ namespace IKVM.Internal
|
||||||
}
|
}
|
||||||
ilgen.Emit(OpCodes.Callvirt, overrideMethod);
|
ilgen.Emit(OpCodes.Callvirt, overrideMethod);
|
||||||
}
|
}
|
||||||
this.ReturnType.EmitConvStackToParameterType(ilgen, null);
|
this.ReturnType.EmitConvStackTypeToSignatureType(ilgen, null);
|
||||||
ilgen.Emit(OpCodes.Ret);
|
ilgen.Emit(OpCodes.Ret);
|
||||||
}
|
}
|
||||||
ilgen.EmitLineNumberTable(mbHelper);
|
ilgen.EmitLineNumberTable(mbHelper);
|
||||||
|
@ -1439,7 +1440,7 @@ namespace IKVM.Internal
|
||||||
{
|
{
|
||||||
RemapperTypeWrapper typeWrapper = (RemapperTypeWrapper)DeclaringType;
|
RemapperTypeWrapper typeWrapper = (RemapperTypeWrapper)DeclaringType;
|
||||||
Type[] argTypes = new Type[paramTypes.Length + 1];
|
Type[] argTypes = new Type[paramTypes.Length + 1];
|
||||||
argTypes[0] = typeWrapper.TypeAsParameterType;
|
argTypes[0] = typeWrapper.TypeAsSignatureType;
|
||||||
this.GetParametersForDefineMethod().CopyTo(argTypes, 1);
|
this.GetParametersForDefineMethod().CopyTo(argTypes, 1);
|
||||||
MethodBuilder mb = typeWrapper.typeBuilder.DefineMethod("nonvirtualhelper/" + this.Name, MethodAttributes.Private | MethodAttributes.Static, this.ReturnTypeForDefineMethod, argTypes);
|
MethodBuilder mb = typeWrapper.typeBuilder.DefineMethod("nonvirtualhelper/" + this.Name, MethodAttributes.Private | MethodAttributes.Static, this.ReturnTypeForDefineMethod, argTypes);
|
||||||
AttributeHelper.HideFromJava(mb);
|
AttributeHelper.HideFromJava(mb);
|
||||||
|
@ -1504,13 +1505,6 @@ namespace IKVM.Internal
|
||||||
mw.Link();
|
mw.Link();
|
||||||
mw.EmitCall(ilgen);
|
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;
|
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;
|
object constant;
|
||||||
if(f.Constant != null)
|
if(f.Constant != null)
|
||||||
{
|
{
|
||||||
|
@ -1650,27 +1644,31 @@ namespace IKVM.Internal
|
||||||
Hashtable methods = new Hashtable();
|
Hashtable methods = new Hashtable();
|
||||||
foreach(MethodInfo mi in typeBuilder.BaseType.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static))
|
foreach(MethodInfo mi in typeBuilder.BaseType.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static))
|
||||||
{
|
{
|
||||||
ParameterInfo[] paramInfo = mi.GetParameters();
|
string key = MakeMethodKey(mi);
|
||||||
Type[] paramTypes = new Type[paramInfo.Length];
|
if(!methods.ContainsKey(key))
|
||||||
for(int i = 0; i < paramInfo.Length; i++)
|
|
||||||
{
|
{
|
||||||
paramTypes[i] = paramInfo[i].ParameterType;
|
ParameterInfo[] paramInfo = mi.GetParameters();
|
||||||
|
Type[] paramTypes = new Type[paramInfo.Length];
|
||||||
|
for(int i = 0; i < paramInfo.Length; i++)
|
||||||
|
{
|
||||||
|
paramTypes[i] = paramInfo[i].ParameterType;
|
||||||
|
}
|
||||||
|
MethodBuilder mb = typeBuilder.DefineMethod(mi.Name, mi.Attributes & ~(MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.NewSlot), mi.ReturnType, paramTypes);
|
||||||
|
AttributeHelper.HideFromJava(mb);
|
||||||
|
AttributeHelper.SetEditorBrowsableNever(mb);
|
||||||
|
ILGenerator ilgen = mb.GetILGenerator();
|
||||||
|
for(int i = 0; i < paramTypes.Length; i++)
|
||||||
|
{
|
||||||
|
ilgen.Emit(OpCodes.Ldarg_S, (byte)i);
|
||||||
|
}
|
||||||
|
if(!mi.IsStatic)
|
||||||
|
{
|
||||||
|
ilgen.Emit(OpCodes.Ldarg_S, (byte)paramTypes.Length);
|
||||||
|
}
|
||||||
|
ilgen.Emit(OpCodes.Call, mi);
|
||||||
|
ilgen.Emit(OpCodes.Ret);
|
||||||
|
methods[key] = mb;
|
||||||
}
|
}
|
||||||
MethodBuilder mb = typeBuilder.DefineMethod(mi.Name, mi.Attributes & ~(MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.NewSlot), mi.ReturnType, paramTypes);
|
|
||||||
AttributeHelper.HideFromJava(mb);
|
|
||||||
AttributeHelper.SetEditorBrowsableNever(mb);
|
|
||||||
ILGenerator ilgen = mb.GetILGenerator();
|
|
||||||
for(int i = 0; i < paramTypes.Length; i++)
|
|
||||||
{
|
|
||||||
ilgen.Emit(OpCodes.Ldarg_S, (byte)i);
|
|
||||||
}
|
|
||||||
if(!mi.IsStatic)
|
|
||||||
{
|
|
||||||
ilgen.Emit(OpCodes.Ldarg_S, (byte)paramTypes.Length);
|
|
||||||
}
|
|
||||||
ilgen.Emit(OpCodes.Call, mi);
|
|
||||||
ilgen.Emit(OpCodes.Ret);
|
|
||||||
methods[mb.Name] = mb;
|
|
||||||
}
|
}
|
||||||
foreach(PropertyInfo pi in typeBuilder.BaseType.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static))
|
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);
|
PropertyBuilder pb = typeBuilder.DefineProperty(pi.Name, pi.Attributes, pi.PropertyType, paramTypes);
|
||||||
if(pi.CanRead)
|
if(pi.CanRead)
|
||||||
{
|
{
|
||||||
pb.SetGetMethod((MethodBuilder)methods[pi.GetGetMethod().Name]);
|
pb.SetGetMethod((MethodBuilder)methods[MakeMethodKey(pi.GetGetMethod())]);
|
||||||
}
|
}
|
||||||
if(pi.CanWrite)
|
if(pi.CanWrite)
|
||||||
{
|
{
|
||||||
pb.SetSetMethod((MethodBuilder)methods[pi.GetSetMethod().Name]);
|
pb.SetSetMethod((MethodBuilder)methods[MakeMethodKey(pi.GetSetMethod())]);
|
||||||
}
|
}
|
||||||
AttributeHelper.SetEditorBrowsableNever(pb);
|
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)
|
private void CreateShadowInstanceOf(ICollection remappedTypes)
|
||||||
{
|
{
|
||||||
// FXBUG .NET 1.1 doesn't allow static methods on interfaces
|
// FXBUG .NET 1.1 doesn't allow static methods on interfaces
|
||||||
|
|
Загрузка…
Ссылка в новой задаче