Permalink
Fetching contributors…
Cannot retrieve contributors at this time
8512 lines (7851 sloc) 223 KB
/*
Copyright (C) 2007-2011 Jeroen Frijters
Copyright (C) 2009 Volker Berlin (i-net software)
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Jeroen Frijters
jeroen@frijters.net
*/
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Text;
using System.Threading;
using System.Runtime.InteropServices;
using StackFrame = System.Diagnostics.StackFrame;
using StackTrace = System.Diagnostics.StackTrace;
using SystemArray = System.Array;
using SystemDouble = System.Double;
using SystemTimeZone = System.TimeZone;
using SystemThreadingThread = System.Threading.Thread;
using SystemThreadingThreadInterruptedException = System.Threading.ThreadInterruptedException;
using SystemThreadingThreadPriority = System.Threading.ThreadPriority;
using IKVM.Internal;
using jiFile = java.io.File;
using jiObjectStreamField = java.io.ObjectStreamField;
using jlClass = java.lang.Class;
using jlClassLoader = java.lang.ClassLoader;
using jlrConstructor = java.lang.reflect.Constructor;
using jlStackTraceElement = java.lang.StackTraceElement;
using jnByteBuffer = java.nio.ByteBuffer;
using ProtectionDomain = java.security.ProtectionDomain;
#if !FIRST_PASS
using jlArrayIndexOutOfBoundsException = java.lang.ArrayIndexOutOfBoundsException;
using jlClassNotFoundException = java.lang.ClassNotFoundException;
using jlException = java.lang.Exception;
using jlIllegalAccessException = java.lang.IllegalAccessException;
using jlIllegalArgumentException = java.lang.IllegalArgumentException;
using jlInterruptedException = java.lang.InterruptedException;
using jlInternalError = java.lang.InternalError;
using jlNegativeArraySizeException = java.lang.NegativeArraySizeException;
using jlNoClassDefFoundError = java.lang.NoClassDefFoundError;
using jlNullPointerException = java.lang.NullPointerException;
using jlRunnable = java.lang.Runnable;
using jlRuntimeException = java.lang.RuntimeException;
using jlSecurityManager = java.lang.SecurityManager;
using jlSystem = java.lang.System;
using jlThread = java.lang.Thread;
using jlThreadDeath = java.lang.ThreadDeath;
using jlThreadGroup = java.lang.ThreadGroup;
using jlRuntimePermission = java.lang.RuntimePermission;
using jlBoolean = java.lang.Boolean;
using jlByte = java.lang.Byte;
using jlShort = java.lang.Short;
using jlCharacter = java.lang.Character;
using jlInteger = java.lang.Integer;
using jlFloat = java.lang.Float;
using jlLong = java.lang.Long;
using jlDouble = java.lang.Double;
using jlVoid = java.lang.Void;
using jlNumber = java.lang.Number;
using jlrMethod = java.lang.reflect.Method;
using jlrField = java.lang.reflect.Field;
using jlrModifier = java.lang.reflect.Modifier;
using jlrAccessibleObject = java.lang.reflect.AccessibleObject;
using jlrInvocationTargetException = java.lang.reflect.InvocationTargetException;
using srMethodAccessor = sun.reflect.MethodAccessor;
using srConstructorAccessor = sun.reflect.ConstructorAccessor;
using srFieldAccessor = sun.reflect.FieldAccessor;
using srLangReflectAccess = sun.reflect.LangReflectAccess;
using srReflection = sun.reflect.Reflection;
using srReflectionFactory = sun.reflect.ReflectionFactory;
using StubGenerator = ikvm.@internal.stubgen.StubGenerator;
using Annotation = java.lang.annotation.Annotation;
using smJavaIOAccess = sun.misc.JavaIOAccess;
using smLauncher = sun.misc.Launcher;
using smSharedSecrets = sun.misc.SharedSecrets;
using smVM = sun.misc.VM;
using jiConsole = java.io.Console;
using jiIOException = java.io.IOException;
using jnCharset = java.nio.charset.Charset;
using juProperties = java.util.Properties;
using irUtil = ikvm.runtime.Util;
using iiFieldReflectorBase = ikvm.@internal.FieldReflectorBase;
using juzZipFile = java.util.zip.ZipFile;
using juzZipEntry = java.util.zip.ZipEntry;
using juEnumeration = java.util.Enumeration;
using jiInputStream = java.io.InputStream;
using jsAccessController = java.security.AccessController;
using jsAccessControlContext = java.security.AccessControlContext;
using jsPrivilegedAction = java.security.PrivilegedAction;
using jsPrivilegedExceptionAction = java.security.PrivilegedExceptionAction;
using jsPrivilegedActionException = java.security.PrivilegedActionException;
using jnUnknownHostException = java.net.UnknownHostException;
using jnInetAddress = java.net.InetAddress;
using jnInet4Address = java.net.Inet4Address;
using jnInet6Address = java.net.Inet6Address;
using jnNetworkInterface = java.net.NetworkInterface;
using jnInterfaceAddress = java.net.InterfaceAddress;
using ssaGetPropertyAction = sun.security.action.GetPropertyAction;
#endif
namespace IKVM.Runtime
{
public static class Assertions
{
private static bool sysAsserts;
private static bool userAsserts;
private static OptionNode classes;
private static OptionNode packages;
private sealed class OptionNode
{
internal readonly string name;
internal readonly bool enabled;
internal readonly OptionNode next;
internal OptionNode(string name, bool enabled, OptionNode next)
{
this.name = name;
this.enabled = enabled;
this.next = next;
}
}
private static void AddOption(string classOrPackage, bool enabled)
{
if (classOrPackage == null)
{
throw new ArgumentNullException("classOrPackage");
}
if (classOrPackage.EndsWith("..."))
{
packages = new OptionNode(classOrPackage.Substring(0, classOrPackage.Length - 3), enabled, packages);
}
else
{
classes = new OptionNode(classOrPackage, enabled, classes);
}
}
public static void EnableAssertions(string classOrPackage)
{
AddOption(classOrPackage, true);
}
public static void DisableAssertions(string classOrPackage)
{
AddOption(classOrPackage, false);
}
public static void EnableAssertions()
{
userAsserts = true;
}
public static void DisableAssertions()
{
userAsserts = false;
}
public static void EnableSystemAssertions()
{
sysAsserts = true;
}
public static void DisableSystemAssertions()
{
sysAsserts = false;
}
internal static bool IsEnabled(TypeWrapper tw)
{
string className = tw.Name;
// match class name
for (OptionNode n = classes; n != null; n = n.next)
{
if (n.name == className)
{
return n.enabled;
}
}
// match package name
if (packages != null)
{
int len = className.Length;
while (len > 0 && className[--len] != '.') ;
do
{
for (OptionNode n = packages; n != null; n = n.next)
{
if (String.Compare(n.name, 0, className, 0, len, false, System.Globalization.CultureInfo.InvariantCulture) == 0 && len == n.name.Length)
{
return n.enabled;
}
}
while (len > 0 && className[--len] != '.') ;
} while (len > 0);
}
return tw.GetClassLoader() == ClassLoaderWrapper.GetBootstrapClassLoader() ? sysAsserts : userAsserts;
}
private static int Count(OptionNode n)
{
int count = 0;
while (n != null)
{
count++;
n = n.next;
}
return count;
}
internal static object RetrieveDirectives()
{
#if FIRST_PASS
return null;
#else
java.lang.AssertionStatusDirectives asd = new java.lang.AssertionStatusDirectives();
string[] arrStrings = new string[Count(classes)];
bool[] arrBools = new bool[arrStrings.Length];
OptionNode n = classes;
for (int i = 0; i < arrStrings.Length; i++)
{
arrStrings[i] = n.name;
arrBools[i] = n.enabled;
n = n.next;
}
asd.classes = arrStrings;
asd.classEnabled = arrBools;
arrStrings = new string[Count(packages)];
arrBools = new bool[arrStrings.Length];
n = packages;
for (int i = 0; i < arrStrings.Length; i++)
{
arrStrings[i] = n.name;
arrBools[i] = n.enabled;
n = n.next;
}
asd.packages = arrStrings;
asd.packageEnabled = arrBools;
asd.deflt = userAsserts;
return asd;
#endif
}
}
}
static class DynamicMethodUtils
{
#if NET_4_0
private static Module dynamicModule;
#endif
[System.Security.SecuritySafeCritical]
internal static DynamicMethod Create(string name, Type owner, bool nonPublic, Type returnType, Type[] paramTypes)
{
try
{
#if NET_4_0
if (dynamicModule == null)
{
// we have to create a module that is security critical to hold the dynamic method, if we want to be able to emit unverifiable code
AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("<DynamicMethodHolder>"), AssemblyBuilderAccess.RunAndCollect);
Interlocked.CompareExchange(ref dynamicModule, ab.DefineDynamicModule("<DynamicMethodHolder>"), null);
}
return new DynamicMethod(name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, paramTypes, dynamicModule, true);
#else
if (!ReflectUtil.CanOwnDynamicMethod(owner))
{
// interfaces and arrays aren't allowed as owners of dynamic methods
return new DynamicMethod(name, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, returnType, paramTypes, owner.Module, true);
}
else
{
return new DynamicMethod(name, returnType, paramTypes, owner);
}
#endif
}
catch (System.Security.SecurityException)
{
if (nonPublic && !RestrictedMemberAccess)
{
// we don't have RestrictedMemberAccess, so we stick the dynamic method in our module and hope for the best
// (i.e. that we're trying to access something with assembly access in an assembly that lets us)
return new DynamicMethod(name, returnType, paramTypes, typeof(DynamicMethodUtils).Module);
}
// apparently we don't have full trust, so we try again with .NET 2.0 SP1 method
// and we only request restrictSkipVisibility if it is required
return new DynamicMethod(name, returnType, paramTypes, nonPublic);
}
}
private static bool RestrictedMemberAccess
{
get
{
try
{
new System.Security.Permissions.ReflectionPermission(System.Security.Permissions.ReflectionPermissionFlag.RestrictedMemberAccess).Demand();
return true;
}
catch (System.Security.SecurityException)
{
return false;
}
}
}
}
namespace IKVM.NativeCode.ikvm.runtime
{
static class Startup
{
// this method is called from ikvm.runtime.Startup.exitMainThread() and from JNI's DetachCurrentThread
public static void jniDetach()
{
#if !FIRST_PASS
jlThread.currentThread().die();
#endif
}
public static void addBootClassPathAssemby(Assembly asm)
{
ClassLoaderWrapper.GetBootstrapClassLoader().AddDelegate(global::IKVM.Internal.AssemblyClassLoader.FromAssembly(asm));
}
}
}
namespace IKVM.NativeCode.java
{
namespace io
{
static class Console
{
public static string encoding()
{
int cp = 437;
try
{
cp = global::System.Console.InputEncoding.CodePage;
}
catch
{
}
if (cp >= 874 && cp <= 950)
{
return "ms" + cp;
}
return "cp" + cp;
}
private const int STD_INPUT_HANDLE = -10;
private const int ENABLE_ECHO_INPUT = 0x0004;
[System.Runtime.InteropServices.DllImport("kernel32")]
private static extern IntPtr GetStdHandle(int nStdHandle);
[System.Runtime.InteropServices.DllImport("kernel32")]
private static extern int GetConsoleMode(IntPtr hConsoleHandle, out int lpMode);
[System.Runtime.InteropServices.DllImport("kernel32")]
private static extern int SetConsoleMode(IntPtr hConsoleHandle, int dwMode);
public static bool echo(bool on)
{
#if !FIRST_PASS
// HACK the only way to get this to work is by p/invoking the Win32 APIs
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
{
IntPtr hStdIn = GetStdHandle(STD_INPUT_HANDLE);
if (hStdIn.ToInt64() == 0 || hStdIn.ToInt64() == -1)
{
throw new global::java.io.IOException("The handle is invalid");
}
int fdwMode;
if (GetConsoleMode(hStdIn, out fdwMode) == 0)
{
throw new global::java.io.IOException("GetConsoleMode failed");
}
bool old = (fdwMode & ENABLE_ECHO_INPUT) != 0;
if (on)
{
fdwMode |= ENABLE_ECHO_INPUT;
}
else
{
fdwMode &= ~ENABLE_ECHO_INPUT;
}
if (SetConsoleMode(hStdIn, fdwMode) == 0)
{
throw new global::java.io.IOException("SetConsoleMode failed");
}
return old;
}
#endif
return true;
}
public static bool istty()
{
// The JDK returns false here if stdin or stdout (not stderr) is redirected to a file
// or if there is no console associated with the current process.
// The best we can do is to look at the KeyAvailable property, which
// will throw an InvalidOperationException if stdin is redirected or not available
try
{
return global::System.Console.KeyAvailable || true;
}
catch (InvalidOperationException)
{
return false;
}
}
}
static class FileDescriptor
{
private static Converter<int, int> fsync;
public static System.IO.Stream open(String name, System.IO.FileMode fileMode, System.IO.FileAccess fileAccess)
{
if (VirtualFileSystem.IsVirtualFS(name))
{
return VirtualFileSystem.Open(name, fileMode, fileAccess);
}
else if (fileMode == System.IO.FileMode.Append)
{
// this is the way to get atomic append behavior for all writes
return new System.IO.FileStream(name, fileMode, System.Security.AccessControl.FileSystemRights.AppendData, System.IO.FileShare.ReadWrite, 1, System.IO.FileOptions.None);
}
else
{
return new System.IO.FileStream(name, fileMode, fileAccess, System.IO.FileShare.ReadWrite, 1, false);
}
}
[System.Security.SecuritySafeCritical]
public static bool flushPosix(System.IO.FileStream fs)
{
if (fsync == null)
{
ResolveFSync();
}
bool success = false;
Microsoft.Win32.SafeHandles.SafeFileHandle handle = fs.SafeFileHandle;
RuntimeHelpers.PrepareConstrainedRegions();
try
{
handle.DangerousAddRef(ref success);
return fsync(handle.DangerousGetHandle().ToInt32()) == 0;
}
finally
{
if (success)
{
handle.DangerousRelease();
}
}
}
[System.Security.SecurityCritical]
private static void ResolveFSync()
{
// we don't want a build time dependency on this Mono assembly, so we use reflection
Type type = Type.GetType("Mono.Unix.Native.Syscall, Mono.Posix, Version=2.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756");
if (type != null)
{
fsync = (Converter<int, int>)Delegate.CreateDelegate(typeof(Converter<int, int>), type, "fsync", false, false);
}
if (fsync == null)
{
fsync = DummyFSync;
}
}
private static int DummyFSync(int fd)
{
return 0;
}
}
static class FileSystem
{
public static object getFileSystem()
{
#if FIRST_PASS
return null;
#else
if (JVM.IsUnix)
{
return new global::java.io.UnixFileSystem();
}
else
{
return new global::java.io.Win32FileSystem();
}
#endif
}
}
static class ObjectInputStream
{
public static void bytesToFloats(byte[] src, int srcpos, float[] dst, int dstpos, int nfloats)
{
IKVM.Runtime.FloatConverter converter = new IKVM.Runtime.FloatConverter();
for (int i = 0; i < nfloats; i++)
{
int v = src[srcpos++];
v = (v << 8) | src[srcpos++];
v = (v << 8) | src[srcpos++];
v = (v << 8) | src[srcpos++];
dst[dstpos++] = IKVM.Runtime.FloatConverter.ToFloat(v, ref converter);
}
}
public static void bytesToDoubles(byte[] src, int srcpos, double[] dst, int dstpos, int ndoubles)
{
IKVM.Runtime.DoubleConverter converter = new IKVM.Runtime.DoubleConverter();
for (int i = 0; i < ndoubles; i++)
{
long v = src[srcpos++];
v = (v << 8) | src[srcpos++];
v = (v << 8) | src[srcpos++];
v = (v << 8) | src[srcpos++];
v = (v << 8) | src[srcpos++];
v = (v << 8) | src[srcpos++];
v = (v << 8) | src[srcpos++];
v = (v << 8) | src[srcpos++];
dst[dstpos++] = IKVM.Runtime.DoubleConverter.ToDouble(v, ref converter);
}
}
public static object latestUserDefinedLoader()
{
// testing shows that it is cheaper the get the full stack trace and then look at a few frames than getting the frames individually
StackTrace trace = new StackTrace(2, false);
for (int i = 0; i < trace.FrameCount; i++)
{
StackFrame frame = trace.GetFrame(i);
MethodBase method = frame.GetMethod();
if (method == null)
{
continue;
}
Type type = method.DeclaringType;
if (type != null)
{
TypeWrapper tw = ClassLoaderWrapper.GetWrapperFromType(type);
if (tw != null)
{
ClassLoaderWrapper classLoader = tw.GetClassLoader();
AssemblyClassLoader acl = classLoader as AssemblyClassLoader;
if (acl == null || acl.GetAssembly(tw) != typeof(object).Assembly)
{
object javaClassLoader = classLoader.GetJavaClassLoader();
if (javaClassLoader != null)
{
return javaClassLoader;
}
}
}
}
}
return null;
}
}
static class ObjectOutputStream
{
public static void floatsToBytes(float[] src, int srcpos, byte[] dst, int dstpos, int nfloats)
{
IKVM.Runtime.FloatConverter converter = new IKVM.Runtime.FloatConverter();
for (int i = 0; i < nfloats; i++)
{
int v = IKVM.Runtime.FloatConverter.ToInt(src[srcpos++], ref converter);
dst[dstpos++] = (byte)(v >> 24);
dst[dstpos++] = (byte)(v >> 16);
dst[dstpos++] = (byte)(v >> 8);
dst[dstpos++] = (byte)(v >> 0);
}
}
public static void doublesToBytes(double[] src, int srcpos, byte[] dst, int dstpos, int ndoubles)
{
IKVM.Runtime.DoubleConverter converter = new IKVM.Runtime.DoubleConverter();
for (int i = 0; i < ndoubles; i++)
{
long v = IKVM.Runtime.DoubleConverter.ToLong(src[srcpos++], ref converter);
dst[dstpos++] = (byte)(v >> 56);
dst[dstpos++] = (byte)(v >> 48);
dst[dstpos++] = (byte)(v >> 40);
dst[dstpos++] = (byte)(v >> 32);
dst[dstpos++] = (byte)(v >> 24);
dst[dstpos++] = (byte)(v >> 16);
dst[dstpos++] = (byte)(v >> 8);
dst[dstpos++] = (byte)(v >> 0);
}
}
}
public static class IOHelpers
{
public static void WriteByte(byte[] buf, int offset, byte value)
{
buf[offset] = value;
}
public static void WriteBoolean(byte[] buf, int offset, bool value)
{
buf[offset] = value ? (byte)1 : (byte)0;
}
public static void WriteChar(byte[] buf, int offset, char value)
{
buf[offset + 0] = (byte)(value >> 8);
buf[offset + 1] = (byte)(value >> 0);
}
public static void WriteShort(byte[] buf, int offset, short value)
{
buf[offset + 0] = (byte)(value >> 8);
buf[offset + 1] = (byte)(value >> 0);
}
public static void WriteInt(byte[] buf, int offset, int value)
{
buf[offset + 0] = (byte)(value >> 24);
buf[offset + 1] = (byte)(value >> 16);
buf[offset + 2] = (byte)(value >> 8);
buf[offset + 3] = (byte)(value >> 0);
}
public static void WriteFloat(byte[] buf, int offset, float value)
{
#if !FIRST_PASS
global::java.io.Bits.putFloat(buf, offset, value);
#endif
}
public static void WriteLong(byte[] buf, int offset, long value)
{
WriteInt(buf, offset, (int)(value >> 32));
WriteInt(buf, offset + 4, (int)value);
}
public static void WriteDouble(byte[] buf, int offset, double value)
{
#if !FIRST_PASS
global::java.io.Bits.putDouble(buf, offset, value);
#endif
}
public static byte ReadByte(byte[] buf, int offset)
{
return buf[offset];
}
public static bool ReadBoolean(byte[] buf, int offset)
{
return buf[offset] != 0;
}
public static char ReadChar(byte[] buf, int offset)
{
return (char)((buf[offset] << 8) + buf[offset + 1]);
}
public static short ReadShort(byte[] buf, int offset)
{
return (short)((buf[offset] << 8) + buf[offset + 1]);
}
public static int ReadInt(byte[] buf, int offset)
{
return (buf[offset + 0] << 24)
+ (buf[offset + 1] << 16)
+ (buf[offset + 2] << 8)
+ (buf[offset + 3] << 0);
}
public static float ReadFloat(byte[] buf, int offset)
{
#if FIRST_PASS
return 0;
#else
return jlFloat.intBitsToFloat(ReadInt(buf, offset));
#endif
}
public static long ReadLong(byte[] buf, int offset)
{
long hi = (uint)ReadInt(buf, offset);
long lo = (uint)ReadInt(buf, offset + 4);
return lo + (hi << 32);
}
public static double ReadDouble(byte[] buf, int offset)
{
#if FIRST_PASS
return 0;
#else
return jlDouble.longBitsToDouble(ReadLong(buf, offset));
#endif
}
}
static class ObjectStreamClass
{
public static void initNative()
{
}
public static bool isDynamicTypeWrapper(jlClass cl)
{
TypeWrapper wrapper = TypeWrapper.FromClass(cl);
return !wrapper.IsFastClassLiteralSafe;
}
public static bool hasStaticInitializer(jlClass cl)
{
TypeWrapper wrapper = TypeWrapper.FromClass(cl);
try
{
wrapper.Finish();
}
catch (RetargetableJavaException x)
{
throw x.ToJava();
}
Type type = wrapper.TypeAsTBD;
if (!type.IsArray && type.TypeInitializer != null)
{
wrapper.RunClassInit();
return !AttributeHelper.IsHideFromJava(type.TypeInitializer);
}
return false;
}
#if !FIRST_PASS
private sealed class FastFieldReflector : iiFieldReflectorBase
{
private static readonly MethodInfo ReadByteMethod = typeof(IOHelpers).GetMethod("ReadByte");
private static readonly MethodInfo ReadBooleanMethod = typeof(IOHelpers).GetMethod("ReadBoolean");
private static readonly MethodInfo ReadCharMethod = typeof(IOHelpers).GetMethod("ReadChar");
private static readonly MethodInfo ReadShortMethod = typeof(IOHelpers).GetMethod("ReadShort");
private static readonly MethodInfo ReadIntMethod = typeof(IOHelpers).GetMethod("ReadInt");
private static readonly MethodInfo ReadFloatMethod = typeof(IOHelpers).GetMethod("ReadFloat");
private static readonly MethodInfo ReadLongMethod = typeof(IOHelpers).GetMethod("ReadLong");
private static readonly MethodInfo ReadDoubleMethod = typeof(IOHelpers).GetMethod("ReadDouble");
private static readonly MethodInfo WriteByteMethod = typeof(IOHelpers).GetMethod("WriteByte");
private static readonly MethodInfo WriteBooleanMethod = typeof(IOHelpers).GetMethod("WriteBoolean");
private static readonly MethodInfo WriteCharMethod = typeof(IOHelpers).GetMethod("WriteChar");
private static readonly MethodInfo WriteShortMethod = typeof(IOHelpers).GetMethod("WriteShort");
private static readonly MethodInfo WriteIntMethod = typeof(IOHelpers).GetMethod("WriteInt");
private static readonly MethodInfo WriteFloatMethod = typeof(IOHelpers).GetMethod("WriteFloat");
private static readonly MethodInfo WriteLongMethod = typeof(IOHelpers).GetMethod("WriteLong");
private static readonly MethodInfo WriteDoubleMethod = typeof(IOHelpers).GetMethod("WriteDouble");
private delegate void ObjFieldGetterSetter(object obj, object[] objarr);
private delegate void PrimFieldGetterSetter(object obj, byte[] objarr);
private static readonly ObjFieldGetterSetter objDummy = new ObjFieldGetterSetter(Dummy);
private static readonly PrimFieldGetterSetter primDummy = new PrimFieldGetterSetter(Dummy);
private jiObjectStreamField[] fields;
private ObjFieldGetterSetter objFieldGetter;
private PrimFieldGetterSetter primFieldGetter;
private ObjFieldGetterSetter objFieldSetter;
private PrimFieldGetterSetter primFieldSetter;
private static void Dummy(object obj, object[] objarr)
{
}
private static void Dummy(object obj, byte[] barr)
{
}
internal FastFieldReflector(jiObjectStreamField[] fields)
{
this.fields = fields;
TypeWrapper tw = null;
foreach (jiObjectStreamField field in fields)
{
FieldWrapper fw = GetFieldWrapper(field);
if (fw != null)
{
if (tw == null)
{
tw = fw.DeclaringType;
}
else if (tw != fw.DeclaringType)
{
// pre-condition is that all fields are from the same Type!
throw new jlInternalError();
}
}
}
if (tw == null)
{
objFieldGetter = objFieldSetter = objDummy;
primFieldGetter = primFieldSetter = primDummy;
}
else
{
try
{
tw.Finish();
}
catch (RetargetableJavaException x)
{
throw x.ToJava();
}
DynamicMethod dmObjGetter = DynamicMethodUtils.Create("__<ObjFieldGetter>", tw.TypeAsBaseType, true, null, new Type[] { typeof(object), typeof(object[]) });
DynamicMethod dmPrimGetter = DynamicMethodUtils.Create("__<PrimFieldGetter>", tw.TypeAsBaseType, true, null, new Type[] { typeof(object), typeof(byte[]) });
DynamicMethod dmObjSetter = DynamicMethodUtils.Create("__<ObjFieldSetter>", tw.TypeAsBaseType, true, null, new Type[] { typeof(object), typeof(object[]) });
DynamicMethod dmPrimSetter = DynamicMethodUtils.Create("__<PrimFieldSetter>", tw.TypeAsBaseType, true, null, new Type[] { typeof(object), typeof(byte[]) });
CodeEmitter ilgenObjGetter = CodeEmitter.Create(dmObjGetter);
CodeEmitter ilgenPrimGetter = CodeEmitter.Create(dmPrimGetter);
CodeEmitter ilgenObjSetter = CodeEmitter.Create(dmObjSetter);
CodeEmitter ilgenPrimSetter = CodeEmitter.Create(dmPrimSetter);
// we want the getters to be verifiable (because writeObject can be used from partial trust),
// so we create a local to hold the properly typed object reference
CodeEmitterLocal objGetterThis = ilgenObjGetter.DeclareLocal(tw.TypeAsBaseType);
CodeEmitterLocal primGetterThis = ilgenPrimGetter.DeclareLocal(tw.TypeAsBaseType);
ilgenObjGetter.Emit(OpCodes.Ldarg_0);
ilgenObjGetter.Emit(OpCodes.Castclass, tw.TypeAsBaseType);
ilgenObjGetter.Emit(OpCodes.Stloc, objGetterThis);
ilgenPrimGetter.Emit(OpCodes.Ldarg_0);
ilgenPrimGetter.Emit(OpCodes.Castclass, tw.TypeAsBaseType);
ilgenPrimGetter.Emit(OpCodes.Stloc, primGetterThis);
foreach (jiObjectStreamField field in fields)
{
FieldWrapper fw = GetFieldWrapper(field);
if (fw == null)
{
continue;
}
fw.ResolveField();
TypeWrapper fieldType = fw.FieldTypeWrapper;
try
{
fieldType.Finish();
}
catch (RetargetableJavaException x)
{
throw x.ToJava();
}
if (fieldType.IsPrimitive)
{
// Getter
ilgenPrimGetter.Emit(OpCodes.Ldarg_1);
ilgenPrimGetter.EmitLdc_I4(field.getOffset());
ilgenPrimGetter.Emit(OpCodes.Ldloc, primGetterThis);
fw.EmitGet(ilgenPrimGetter);
if (fieldType == PrimitiveTypeWrapper.BYTE)
{
ilgenPrimGetter.Emit(OpCodes.Call, WriteByteMethod);
}
else if (fieldType == PrimitiveTypeWrapper.BOOLEAN)
{
ilgenPrimGetter.Emit(OpCodes.Call, WriteBooleanMethod);
}
else if (fieldType == PrimitiveTypeWrapper.CHAR)
{
ilgenPrimGetter.Emit(OpCodes.Call, WriteCharMethod);
}
else if (fieldType == PrimitiveTypeWrapper.SHORT)
{
ilgenPrimGetter.Emit(OpCodes.Call, WriteShortMethod);
}
else if (fieldType == PrimitiveTypeWrapper.INT)
{
ilgenPrimGetter.Emit(OpCodes.Call, WriteIntMethod);
}
else if (fieldType == PrimitiveTypeWrapper.FLOAT)
{
ilgenPrimGetter.Emit(OpCodes.Call, WriteFloatMethod);
}
else if (fieldType == PrimitiveTypeWrapper.LONG)
{
ilgenPrimGetter.Emit(OpCodes.Call, WriteLongMethod);
}
else if (fieldType == PrimitiveTypeWrapper.DOUBLE)
{
ilgenPrimGetter.Emit(OpCodes.Call, WriteDoubleMethod);
}
else
{
throw new jlInternalError();
}
// Setter
ilgenPrimSetter.Emit(OpCodes.Ldarg_0);
ilgenPrimSetter.Emit(OpCodes.Castclass, tw.TypeAsBaseType);
ilgenPrimSetter.Emit(OpCodes.Ldarg_1);
ilgenPrimSetter.EmitLdc_I4(field.getOffset());
if (fieldType == PrimitiveTypeWrapper.BYTE)
{
ilgenPrimSetter.Emit(OpCodes.Call, ReadByteMethod);
}
else if (fieldType == PrimitiveTypeWrapper.BOOLEAN)
{
ilgenPrimSetter.Emit(OpCodes.Call, ReadBooleanMethod);
}
else if (fieldType == PrimitiveTypeWrapper.CHAR)
{
ilgenPrimSetter.Emit(OpCodes.Call, ReadCharMethod);
}
else if (fieldType == PrimitiveTypeWrapper.SHORT)
{
ilgenPrimSetter.Emit(OpCodes.Call, ReadShortMethod);
}
else if (fieldType == PrimitiveTypeWrapper.INT)
{
ilgenPrimSetter.Emit(OpCodes.Call, ReadIntMethod);
}
else if (fieldType == PrimitiveTypeWrapper.FLOAT)
{
ilgenPrimSetter.Emit(OpCodes.Call, ReadFloatMethod);
}
else if (fieldType == PrimitiveTypeWrapper.LONG)
{
ilgenPrimSetter.Emit(OpCodes.Call, ReadLongMethod);
}
else if (fieldType == PrimitiveTypeWrapper.DOUBLE)
{
ilgenPrimSetter.Emit(OpCodes.Call, ReadDoubleMethod);
}
else
{
throw new jlInternalError();
}
fw.EmitSet(ilgenPrimSetter);
}
else
{
// Getter
ilgenObjGetter.Emit(OpCodes.Ldarg_1);
ilgenObjGetter.EmitLdc_I4(field.getOffset());
ilgenObjGetter.Emit(OpCodes.Ldloc, objGetterThis);
fw.EmitGet(ilgenObjGetter);
fw.FieldTypeWrapper.EmitConvSignatureTypeToStackType(ilgenObjGetter);
ilgenObjGetter.Emit(OpCodes.Stelem_Ref);
// Setter
ilgenObjSetter.Emit(OpCodes.Ldarg_0);
ilgenObjSetter.Emit(OpCodes.Ldarg_1);
ilgenObjSetter.EmitLdc_I4(field.getOffset());
ilgenObjSetter.Emit(OpCodes.Ldelem_Ref);
fw.FieldTypeWrapper.EmitCheckcast(null, ilgenObjSetter);
fw.FieldTypeWrapper.EmitConvStackTypeToSignatureType(ilgenObjSetter, null);
fw.EmitSet(ilgenObjSetter);
}
}
ilgenObjGetter.Emit(OpCodes.Ret);
ilgenPrimGetter.Emit(OpCodes.Ret);
ilgenObjSetter.Emit(OpCodes.Ret);
ilgenPrimSetter.Emit(OpCodes.Ret);
ilgenObjGetter.DoEmit();
ilgenPrimGetter.DoEmit();
ilgenObjSetter.DoEmit();
ilgenPrimSetter.DoEmit();
objFieldGetter = (ObjFieldGetterSetter)dmObjGetter.CreateDelegate(typeof(ObjFieldGetterSetter));
primFieldGetter = (PrimFieldGetterSetter)dmPrimGetter.CreateDelegate(typeof(PrimFieldGetterSetter));
objFieldSetter = (ObjFieldGetterSetter)dmObjSetter.CreateDelegate(typeof(ObjFieldGetterSetter));
primFieldSetter = (PrimFieldGetterSetter)dmPrimSetter.CreateDelegate(typeof(PrimFieldGetterSetter));
}
}
private static FieldWrapper GetFieldWrapper(jiObjectStreamField field)
{
jlrField f = field.getField();
return f == null ? null : FieldWrapper.FromField(f);
}
public override jiObjectStreamField[] getFields()
{
return fields;
}
public override void getObjFieldValues(object obj, object[] objarr)
{
objFieldGetter(obj, objarr);
}
public override void setObjFieldValues(object obj, object[] objarr)
{
objFieldSetter(obj, objarr);
}
public override void getPrimFieldValues(object obj, byte[] barr)
{
primFieldGetter(obj, barr);
}
public override void setPrimFieldValues(object obj, byte[] barr)
{
primFieldSetter(obj, barr);
}
}
#endif // !FIRST_PASS
public static object getFastFieldReflector(object fieldsObj)
{
#if FIRST_PASS
return null;
#else
return new FastFieldReflector((jiObjectStreamField[])fieldsObj);
#endif
}
}
static class Win32FileSystem
{
internal const int ACCESS_READ = 0x04;
const int ACCESS_WRITE = 0x02;
const int ACCESS_EXECUTE = 0x01;
public static string getDriveDirectory(object _this, int drive)
{
try
{
string path = ((char)('A' + (drive - 1))) + ":";
return System.IO.Path.GetFullPath(path).Substring(2);
}
catch (ArgumentException)
{
}
catch (System.Security.SecurityException)
{
}
catch (System.IO.PathTooLongException)
{
}
return "\\";
}
private static string CanonicalizePath(string path)
{
try
{
System.IO.FileInfo fi = new System.IO.FileInfo(path);
if (fi.DirectoryName == null)
{
return path.Length > 1 && path[1] == ':'
? (Char.ToUpper(path[0]) + ":" + System.IO.Path.DirectorySeparatorChar)
: path;
}
string dir = CanonicalizePath(fi.DirectoryName);
string name = fi.Name;
try
{
if (!VirtualFileSystem.IsVirtualFS(path))
{
string[] arr = System.IO.Directory.GetFileSystemEntries(dir, name);
if (arr.Length == 1)
{
name = arr[0];
}
}
}
catch (System.UnauthorizedAccessException)
{
}
catch (System.IO.IOException)
{
}
return System.IO.Path.Combine(dir, name);
}
catch (System.UnauthorizedAccessException)
{
}
catch (System.IO.IOException)
{
}
catch (System.Security.SecurityException)
{
}
catch (System.NotSupportedException)
{
}
return path;
}
public static string canonicalize0(object _this, string path)
{
#if FIRST_PASS
return null;
#else
try
{
// TODO there is still a known bug here. A dotted path component right after the root component
// are not removed as they should be. E.g. "c:\..." => "C:\..." or "\\server\..." => IOException
// Another know issue is that when running under Mono on Windows, the case names aren't converted
// to the correct (on file system) casing.
//
// FXBUG we're appending the directory separator to work around an apparent .NET bug.
// If we don't do this, "c:\j\." would be canonicalized to "C:\"
int colon = path.IndexOf(':', 2);
if (colon != -1)
{
return CanonicalizePath(path.Substring(0, colon) + System.IO.Path.DirectorySeparatorChar) + path.Substring(colon);
}
return CanonicalizePath(path + System.IO.Path.DirectorySeparatorChar);
}
catch (System.ArgumentException x)
{
throw new jiIOException(x.Message);
}
#endif
}
public static string canonicalizeWithPrefix0(object _this, string canonicalPrefix, string pathWithCanonicalPrefix)
{
return canonicalize0(_this, pathWithCanonicalPrefix);
}
private static string GetPathFromFile(jiFile file)
{
#if FIRST_PASS
return null;
#else
return file.getPath();
#endif
}
public static int getBooleanAttributes(object _this, jiFile f)
{
try
{
string path = GetPathFromFile(f);
if (VirtualFileSystem.IsVirtualFS(path))
{
return VirtualFileSystem.GetBooleanAttributes(path);
}
System.IO.FileAttributes attr = System.IO.File.GetAttributes(path);
const int BA_EXISTS = 0x01;
const int BA_REGULAR = 0x02;
const int BA_DIRECTORY = 0x04;
const int BA_HIDDEN = 0x08;
int rv = BA_EXISTS;
if ((attr & System.IO.FileAttributes.Directory) != 0)
{
rv |= BA_DIRECTORY;
}
else
{
rv |= BA_REGULAR;
}
if ((attr & System.IO.FileAttributes.Hidden) != 0)
{
rv |= BA_HIDDEN;
}
return rv;
}
catch (System.ArgumentException)
{
}
catch (System.UnauthorizedAccessException)
{
}
catch (System.Security.SecurityException)
{
}
catch (System.NotSupportedException)
{
}
catch (System.IO.IOException)
{
}
return 0;
}
public static bool checkAccess(object _this, jiFile f, int access)
{
string path = GetPathFromFile(f);
if (VirtualFileSystem.IsVirtualFS(path))
{
return VirtualFileSystem.CheckAccess(path, access);
}
bool ok = true;
if ((access & (ACCESS_READ | ACCESS_EXECUTE)) != 0)
{
ok = false;
try
{
// HACK if path refers to a directory, we always return true
if (!System.IO.Directory.Exists(path))
{
new System.IO.FileInfo(path).Open(
System.IO.FileMode.Open,
System.IO.FileAccess.Read,
System.IO.FileShare.ReadWrite).Close();
}
ok = true;
}
catch (System.Security.SecurityException)
{
}
catch (System.ArgumentException)
{
}
catch (System.UnauthorizedAccessException)
{
}
catch (System.IO.IOException)
{
}
catch (System.NotSupportedException)
{
}
}
if (ok && ((access & ACCESS_WRITE) != 0))
{
ok = false;
try
{
// HACK if path refers to a directory, we always return true
if (System.IO.Directory.Exists(path))
{
ok = true;
}
else
{
System.IO.FileInfo fileInfo = new System.IO.FileInfo(path);
// Like the JDK we'll only look at the read-only attribute and not
// the security permissions associated with the file or directory.
ok = (fileInfo.Attributes & System.IO.FileAttributes.ReadOnly) == 0;
}
}
catch (System.Security.SecurityException)
{
}
catch (System.ArgumentException)
{
}
catch (System.UnauthorizedAccessException)
{
}
catch (System.IO.IOException)
{
}
catch (System.NotSupportedException)
{
}
}
return ok;
}
private static long DateTimeToJavaLongTime(System.DateTime datetime)
{
return (System.TimeZone.CurrentTimeZone.ToUniversalTime(datetime) - new System.DateTime(1970, 1, 1)).Ticks / 10000L;
}
private static System.DateTime JavaLongTimeToDateTime(long datetime)
{
return System.TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(new System.DateTime(1970, 1, 1).Ticks + datetime * 10000L));
}
public static long getLastModifiedTime(object _this, jiFile f)
{
try
{
DateTime dt = System.IO.File.GetLastWriteTime(GetPathFromFile(f));
if (dt.ToFileTime() == 0)
{
return 0;
}
else
{
return DateTimeToJavaLongTime(dt);
}
}
catch (System.UnauthorizedAccessException)
{
}
catch (System.ArgumentException)
{
}
catch (System.IO.IOException)
{
}
catch (System.NotSupportedException)
{
}
return 0;
}
public static long getLength(object _this, jiFile f)
{
try
{
string path = GetPathFromFile(f);
if (VirtualFileSystem.IsVirtualFS(path))
{
return VirtualFileSystem.GetLength(path);
}
return new System.IO.FileInfo(path).Length;
}
catch (System.Security.SecurityException)
{
}
catch (System.ArgumentException)
{
}
catch (System.UnauthorizedAccessException)
{
}
catch (System.IO.IOException)
{
}
catch (System.NotSupportedException)
{
}
return 0;
}
public static bool setPermission(object _this, jiFile f, int access, bool enable, bool owneronly)
{
if ((access & ACCESS_WRITE) != 0)
{
try
{
System.IO.FileInfo file = new System.IO.FileInfo(GetPathFromFile(f));
if (enable)
{
file.Attributes &= ~System.IO.FileAttributes.ReadOnly;
}
else
{
file.Attributes |= System.IO.FileAttributes.ReadOnly;
}
return true;
}
catch (System.Security.SecurityException)
{
}
catch (System.ArgumentException)
{
}
catch (System.UnauthorizedAccessException)
{
}
catch (System.IO.IOException)
{
}
catch (System.NotSupportedException)
{
}
return false;
}
return enable;
}
public static bool createFileExclusively(object _this, string path)
{
#if !FIRST_PASS
try
{
System.IO.File.Open(path, System.IO.FileMode.CreateNew, System.IO.FileAccess.ReadWrite, System.IO.FileShare.None).Close();
return true;
}
catch (System.ArgumentException x)
{
throw new jiIOException(x.Message);
}
catch (System.IO.IOException x)
{
if (!System.IO.File.Exists(path) && !System.IO.Directory.Exists(path))
{
throw new jiIOException(x.Message);
}
}
catch (System.UnauthorizedAccessException x)
{
if (!System.IO.File.Exists(path) && !System.IO.Directory.Exists(path))
{
throw new jiIOException(x.Message);
}
}
catch (System.NotSupportedException x)
{
throw new jiIOException(x.Message);
}
#endif
return false;
}
public static bool delete0(object _this, jiFile f)
{
System.IO.FileSystemInfo fileInfo = null;
try
{
string path = GetPathFromFile(f);
if (System.IO.Directory.Exists(path))
{
fileInfo = new System.IO.DirectoryInfo(path);
}
else if (System.IO.File.Exists(path))
{
fileInfo = new System.IO.FileInfo(path);
}
else
{
return false;
}
// We need to be able to delete read-only files/dirs too, so we clear
// the read-only attribute, if set.
if ((fileInfo.Attributes & System.IO.FileAttributes.ReadOnly) != 0)
{
fileInfo.Attributes &= ~System.IO.FileAttributes.ReadOnly;
}
fileInfo.Delete();
return true;
}
catch (System.Security.SecurityException)
{
}
catch (System.ArgumentException)
{
}
catch (System.UnauthorizedAccessException)
{
}
catch (System.IO.IOException)
{
}
catch (System.NotSupportedException)
{
}
return false;
}
public static string[] list(object _this, jiFile f)
{
try
{
string path = GetPathFromFile(f);
if (VirtualFileSystem.IsVirtualFS(path))
{
return VirtualFileSystem.List(path);
}
string[] l = System.IO.Directory.GetFileSystemEntries(path);
for (int i = 0; i < l.Length; i++)
{
int pos = l[i].LastIndexOf(System.IO.Path.DirectorySeparatorChar);
if (pos >= 0)
{
l[i] = l[i].Substring(pos + 1);
}
}
return l;
}
catch (System.ArgumentException)
{
}
catch (System.IO.IOException)
{
}
catch (System.UnauthorizedAccessException)
{
}
catch (System.NotSupportedException)
{
}
return null;
}
public static bool createDirectory(object _this, jiFile f)
{
try
{
string path = GetPathFromFile(f);
System.IO.DirectoryInfo parent = System.IO.Directory.GetParent(path);
if (parent == null ||
!System.IO.Directory.Exists(parent.FullName) ||
System.IO.Directory.Exists(path))
{
return false;
}
return System.IO.Directory.CreateDirectory(path) != null;
}
catch (System.Security.SecurityException)
{
}
catch (System.ArgumentException)
{
}
catch (System.UnauthorizedAccessException)
{
}
catch (System.IO.IOException)
{
}
catch (System.NotSupportedException)
{
}
return false;
}
public static bool rename0(object _this, jiFile f1, jiFile f2)
{
try
{
new System.IO.FileInfo(GetPathFromFile(f1)).MoveTo(GetPathFromFile(f2));
return true;
}
catch (System.Security.SecurityException)
{
}
catch (System.ArgumentException)
{
}
catch (System.UnauthorizedAccessException)
{
}
catch (System.IO.IOException)
{
}
catch (System.NotSupportedException)
{
}
return false;
}
public static bool setLastModifiedTime(object _this, jiFile f, long time)
{
try
{
new System.IO.FileInfo(GetPathFromFile(f)).LastWriteTime = JavaLongTimeToDateTime(time);
return true;
}
catch (System.Security.SecurityException)
{
}
catch (System.ArgumentException)
{
}
catch (System.UnauthorizedAccessException)
{
}
catch (System.IO.IOException)
{
}
catch (System.NotSupportedException)
{
}
return false;
}
public static bool setReadOnly(object _this, jiFile f)
{
try
{
System.IO.FileInfo fileInfo = new System.IO.FileInfo(GetPathFromFile(f));
fileInfo.Attributes |= System.IO.FileAttributes.ReadOnly;
return true;
}
catch (System.Security.SecurityException)
{
}
catch (System.ArgumentException)
{
}
catch (System.UnauthorizedAccessException)
{
}
catch (System.IO.IOException)
{
}
catch (System.NotSupportedException)
{
}
return false;
}
public static int listRoots0()
{
try
{
int drives = 0;
foreach (string drive in Environment.GetLogicalDrives())
{
char c = Char.ToUpper(drive[0]);
drives |= 1 << (c - 'A');
}
return drives;
}
catch (System.IO.IOException)
{
}
catch (System.UnauthorizedAccessException)
{
}
catch (System.Security.SecurityException)
{
}
return 0;
}
[System.Security.SecuritySafeCritical]
public static long getSpace0(object _this, jiFile f, int t)
{
const int SPACE_TOTAL = 0;
const int SPACE_FREE = 1;
const int SPACE_USABLE = 2;
long freeAvailable;
long total;
long totalFree;
if (GetDiskFreeSpaceEx(GetPathFromFile(f), out freeAvailable, out total, out totalFree) != 0)
{
switch (t)
{
case SPACE_TOTAL:
return total;
case SPACE_FREE:
return totalFree;
case SPACE_USABLE:
return freeAvailable;
}
}
return 0;
}
[System.Runtime.InteropServices.DllImport("kernel32")]
private static extern int GetDiskFreeSpaceEx(string directory, out long freeAvailable, out long total, out long totalFree);
public static void initIDs()
{
}
}
static class UnixFileSystem
{
public static int getBooleanAttributes0(object _this, jiFile f)
{
return Win32FileSystem.getBooleanAttributes(_this, f);
}
public static long getSpace(object _this, jiFile f, int t)
{
// TODO
return 0;
}
public static string getDriveDirectory(object _this, int drive)
{
return Win32FileSystem.getDriveDirectory(_this, drive);
}
public static string canonicalize0(object _this, string path)
{
return Win32FileSystem.canonicalize0(_this, path);
}
public static bool checkAccess(object _this, jiFile f, int access)
{
return Win32FileSystem.checkAccess(_this, f, access);
}
public static long getLastModifiedTime(object _this, jiFile f)
{
return Win32FileSystem.getLastModifiedTime(_this, f);
}
public static long getLength(object _this, jiFile f)
{
return Win32FileSystem.getLength(_this, f);
}
public static bool setPermission(object _this, jiFile f, int access, bool enable, bool owneronly)
{
// TODO consider using Mono.Posix
return Win32FileSystem.setPermission(_this, f, access, enable, owneronly);
}
public static bool createFileExclusively(object _this, string path)
{
return Win32FileSystem.createFileExclusively(_this, path);
}
public static bool delete0(object _this, jiFile f)
{
return Win32FileSystem.delete0(_this, f);
}
public static string[] list(object _this, jiFile f)
{
return Win32FileSystem.list(_this, f);
}
public static bool createDirectory(object _this, jiFile f)
{
return Win32FileSystem.createDirectory(_this, f);
}
public static bool rename0(object _this, jiFile f1, jiFile f2)
{
return Win32FileSystem.rename0(_this, f1, f2);
}
public static bool setLastModifiedTime(object _this, jiFile f, long time)
{
return Win32FileSystem.setLastModifiedTime(_this, f, time);
}
public static bool setReadOnly(object _this, jiFile f)
{
return Win32FileSystem.setReadOnly(_this, f);
}
public static void initIDs()
{
}
}
}
namespace lang
{
namespace @ref
{
static class Reference
{
public static bool noclassgc()
{
#if CLASSGC
return !JVM.classUnloading;
#else
return true;
#endif
}
}
}
namespace reflect
{
static class Array
{
#if FIRST_PASS
public static int getLength(object arrayObj)
{
return 0;
}
public static object get(object arrayObj, int index)
{
return null;
}
public static bool getBoolean(object arrayObj, int index)
{
return false;
}
public static byte getByte(object arrayObj, int index)
{
return 0;
}
public static char getChar(object arrayObj, int index)
{
return '\u0000';
}
public static short getShort(object arrayObj, int index)
{
return 0;
}
public static int getInt(object arrayObj, int index)
{
return 0;
}
public static float getFloat(object arrayObj, int index)
{
return 0;
}
public static long getLong(object arrayObj, int index)
{
return 0;
}
public static double getDouble(object arrayObj, int index)
{
return 0;
}
public static void set(object arrayObj, int index, object value)
{
}
public static void setBoolean(object arrayObj, int index, bool value)
{
}
public static void setByte(object arrayObj, int index, byte value)
{
}
public static void setChar(object arrayObj, int index, char value)
{
}
public static void setShort(object arrayObj, int index, short value)
{
}
public static void setInt(object arrayObj, int index, int value)
{
}
public static void setFloat(object arrayObj, int index, float value)
{
}
public static void setLong(object arrayObj, int index, long value)
{
}
public static void setDouble(object arrayObj, int index, double value)
{
}
public static object newArray(jlClass componentType, int length)
{
return null;
}
public static object multiNewArray(jlClass componentType, int[] dimensions)
{
return null;
}
#else
private static SystemArray CheckArray(object arrayObj)
{
if (arrayObj == null)
{
throw new jlNullPointerException();
}
SystemArray arr = arrayObj as SystemArray;
if (arr != null)
{
return arr;
}
throw new jlIllegalArgumentException("Argument is not an array");
}
public static int getLength(object arrayObj)
{
return CheckArray(arrayObj).Length;
}
public static object get(object arrayObj, int index)
{
SystemArray arr = CheckArray(arrayObj);
if (index < 0 || index >= arr.Length)
{
throw new jlArrayIndexOutOfBoundsException();
}
// We need to look at the actual type here, because "is" or "as"
// will convert enums to their underlying type and unsigned integral types
// to their signed counter parts.
Type type = arrayObj.GetType();
if (type == typeof(bool[]))
{
return jlBoolean.valueOf(((bool[])arr)[index]);
}
if (type == typeof(byte[]))
{
return jlByte.valueOf(((byte[])arr)[index]);
}
if (type == typeof(short[]))
{
return jlShort.valueOf(((short[])arr)[index]);
}
if (type == typeof(char[]))
{
return jlCharacter.valueOf(((char[])arr)[index]);
}
if (type == typeof(int[]))
{
return jlInteger.valueOf(((int[])arr)[index]);
}
if (type == typeof(float[]))
{
return jlFloat.valueOf(((float[])arr)[index]);
}
if (type == typeof(long[]))
{
return jlLong.valueOf(((long[])arr)[index]);
}
if (type == typeof(double[]))
{
return jlDouble.valueOf(((double[])arr)[index]);
}
return arr.GetValue(index);
}
public static bool getBoolean(object arrayObj, int index)
{
if (arrayObj == null)
{
throw new jlNullPointerException();
}
bool[] arr = arrayObj as bool[];
if (arr != null)
{
if (index < 0 || index >= arr.Length)
{
throw new jlArrayIndexOutOfBoundsException();
}
return arr[index];
}
throw new jlIllegalArgumentException("argument type mismatch");
}
public static byte getByte(object arrayObj, int index)
{
if (arrayObj == null)
{
throw new jlNullPointerException();
}
byte[] arr = arrayObj as byte[];
if (arr != null)
{
if (index < 0 || index >= arr.Length)
{
throw new jlArrayIndexOutOfBoundsException();
}
return arr[index];
}
throw new jlIllegalArgumentException("argument type mismatch");
}
public static char getChar(object arrayObj, int index)
{
if (arrayObj == null)
{
throw new jlNullPointerException();
}
char[] arr = arrayObj as char[];
if (arr != null)
{
if (index < 0 || index >= arr.Length)
{
throw new jlArrayIndexOutOfBoundsException();
}
return arr[index];
}
throw new jlIllegalArgumentException("argument type mismatch");
}
public static short getShort(object arrayObj, int index)
{
if (arrayObj == null)
{
throw new jlNullPointerException();
}
short[] arr = arrayObj as short[];
if (arr != null)
{
if (index < 0 || index >= arr.Length)
{
throw new jlArrayIndexOutOfBoundsException();
}
return arr[index];
}
return (sbyte)getByte(arrayObj, index);
}
public static int getInt(object arrayObj, int index)
{
if (arrayObj == null)
{
throw new jlNullPointerException();
}
int[] arr1 = arrayObj as int[];
if (arr1 != null)
{
if (index < 0 || index >= arr1.Length)
{
throw new jlArrayIndexOutOfBoundsException();
}
return arr1[index];
}
char[] arr2 = arrayObj as char[];
if (arr2 != null)
{
if (index < 0 || index >= arr2.Length)
{
throw new jlArrayIndexOutOfBoundsException();
}
return arr2[index];
}
return getShort(arrayObj, index);
}
public static float getFloat(object arrayObj, int index)
{
if (arrayObj == null)
{
throw new jlNullPointerException();
}
float[] arr = arrayObj as float[];
if (arr != null)
{
if (index < 0 || index >= arr.Length)
{
throw new jlArrayIndexOutOfBoundsException();
}
return arr[index];
}
return getLong(arrayObj, index);
}
public static long getLong(object arrayObj, int index)
{
if (arrayObj == null)
{
throw new jlNullPointerException();
}
long[] arr = arrayObj as long[];
if (arr != null)
{
if (index < 0 || index >= arr.Length)
{
throw new jlArrayIndexOutOfBoundsException();
}
return arr[index];
}
return getInt(arrayObj, index);
}
public static double getDouble(object arrayObj, int index)
{
if (arrayObj == null)
{
throw new jlNullPointerException();
}
double[] arr = arrayObj as double[];
if (arr != null)
{
if (index < 0 || index >= arr.Length)
{
throw new jlArrayIndexOutOfBoundsException();
}
return arr[index];
}
return getFloat(arrayObj, index);
}
public static void set(object arrayObj, int index, object value)
{
if (arrayObj == null)
{
throw new jlNullPointerException();
}
Type type = arrayObj.GetType();
if (ReflectUtil.IsVector(type) && ClassLoaderWrapper.GetWrapperFromType(type.GetElementType()).IsPrimitive)
{
jlBoolean booleanValue = value as jlBoolean;
if (booleanValue != null)
{
setBoolean(arrayObj, index, booleanValue.booleanValue());
return;
}
jlByte byteValue = value as jlByte;
if (byteValue != null)
{
setByte(arrayObj, index, byteValue.byteValue());
return;
}
jlCharacter charValue = value as jlCharacter;
if (charValue != null)
{
setChar(arrayObj, index, charValue.charValue());
return;
}
jlShort shortValue = value as jlShort;
if (shortValue != null)
{
setShort(arrayObj, index, shortValue.shortValue());
return;
}
jlInteger intValue = value as jlInteger;
if (intValue != null)
{
setInt(arrayObj, index, intValue.intValue());
return;
}
jlFloat floatValue = value as jlFloat;
if (floatValue != null)
{
setFloat(arrayObj, index, floatValue.floatValue());
return;
}
jlLong longValue = value as jlLong;
if (longValue != null)
{
setLong(arrayObj, index, longValue.longValue());
return;
}
jlDouble doubleValue = value as jlDouble;
if (doubleValue != null)
{
setDouble(arrayObj, index, doubleValue.doubleValue());
return;
}
}
try
{
CheckArray(arrayObj).SetValue(value, index);
}
catch (InvalidCastException)
{
throw new jlIllegalArgumentException("argument type mismatch");
}
catch (IndexOutOfRangeException)
{
throw new jlArrayIndexOutOfBoundsException();
}
}
public static void setBoolean(object arrayObj, int index, bool value)
{
if (arrayObj == null)
{
throw new jlNullPointerException();
}
bool[] arr = arrayObj as bool[];
if (arr != null)
{
if (index < 0 || index >= arr.Length)
{
throw new jlArrayIndexOutOfBoundsException();
}
arr[index] = value;
}
else
{
throw new jlIllegalArgumentException("argument type mismatch");
}
}
public static void setByte(object arrayObj, int index, byte value)
{
if (arrayObj == null)
{
throw new jlNullPointerException();
}
byte[] arr = arrayObj as byte[];
if (arr != null)
{
if (index < 0 || index >= arr.Length)
{
throw new jlArrayIndexOutOfBoundsException();
}
arr[index] = value;
}
else
{
setShort(arrayObj, index, (sbyte)value);
}
}
public static void setChar(object arrayObj, int index, char value)
{
if (arrayObj == null)
{
throw new jlNullPointerException();
}
char[] arr = arrayObj as char[];
if (arr != null)
{
if (index < 0 || index >= arr.Length)
{
throw new jlArrayIndexOutOfBoundsException();
}
arr[index] = value;
}
else
{
setInt(arrayObj, index, value);
}
}
public static void setShort(object arrayObj, int index, short value)
{
if (arrayObj == null)
{
throw new jlNullPointerException();
}
short[] arr = arrayObj as short[];
if (arr != null)
{
if (index < 0 || index >= arr.Length)
{
throw new jlArrayIndexOutOfBoundsException();
}
arr[index] = value;
}
else
{
setInt(arrayObj, index, value);
}
}
public static void setInt(object arrayObj, int index, int value)
{
if (arrayObj == null)
{
throw new jlNullPointerException();
}
int[] arr = arrayObj as int[];
if (arr != null)
{
if (index < 0 || index >= arr.Length)
{
throw new jlArrayIndexOutOfBoundsException();
}
arr[index] = value;
}
else
{
setLong(arrayObj, index, value);
}
}
public static void setFloat(object arrayObj, int index, float value)
{
if (arrayObj == null)
{
throw new jlNullPointerException();
}
float[] arr = arrayObj as float[];
if (arr != null)
{
if (index < 0 || index >= arr.Length)
{
throw new jlArrayIndexOutOfBoundsException();
}
arr[index] = value;
}
else
{
setDouble(arrayObj, index, value);
}
}
public static void setLong(object arrayObj, int index, long value)
{
if (arrayObj == null)
{
throw new jlNullPointerException();
}
long[] arr = arrayObj as long[];
if (arr != null)
{
if (index < 0 || index >= arr.Length)
{
throw new jlArrayIndexOutOfBoundsException();
}
arr[index] = value;
}
else
{
setFloat(arrayObj, index, value);
}
}
public static void setDouble(object arrayObj, int index, double value)
{
if (arrayObj == null)
{
throw new jlNullPointerException();
}
double[] arr = arrayObj as double[];
if (arr != null)
{
if (index < 0 || index >= arr.Length)
{
throw new jlArrayIndexOutOfBoundsException();
}
arr[index] = value;
}
else
{
throw new jlIllegalArgumentException("argument type mismatch");
}
}
public static object newArray(jlClass componentType, int length)
{
if (componentType == null)
{
throw new jlNullPointerException();
}
if (componentType == jlVoid.TYPE)
{
throw new jlIllegalArgumentException();
}
if (length < 0)
{
throw new jlNegativeArraySizeException();
}
try
{
TypeWrapper wrapper = TypeWrapper.FromClass(componentType);
wrapper.Finish();
object obj = SystemArray.CreateInstance(wrapper.TypeAsArrayType, length);
if (wrapper.IsGhost || wrapper.IsGhostArray)
{
IKVM.Runtime.GhostTag.SetTag(obj, wrapper.MakeArrayType(1));
}
return obj;
}
catch (RetargetableJavaException x)
{
throw x.ToJava();
}
catch (NotSupportedException x)
{
// This happens when you try to create an array from TypedReference, ArgIterator, ByRef,
// RuntimeArgumentHandle or an open generic type.
throw new jlIllegalArgumentException(x.Message);
}
}
public static object multiNewArray(jlClass componentType, int[] dimensions)
{
if (componentType == null || dimensions == null)
{
throw new jlNullPointerException();
}
if (componentType == jlVoid.TYPE)
{
throw new jlIllegalArgumentException();
}
if (dimensions.Length == 0 || dimensions.Length > 255)
{
throw new jlIllegalArgumentException();
}
try
{
TypeWrapper wrapper = TypeWrapper.FromClass(componentType).MakeArrayType(dimensions.Length);
wrapper.Finish();
object obj = IKVM.Runtime.ByteCodeHelper.multianewarray(wrapper.TypeAsArrayType.TypeHandle, dimensions);
if (wrapper.IsGhostArray)
{
IKVM.Runtime.GhostTag.SetTag(obj, wrapper);
}
return obj;
}
catch (RetargetableJavaException x)
{
throw x.ToJava();
}
catch (NotSupportedException x)
{
// This happens when you try to create an array from TypedReference, ArgIterator, ByRef,
// RuntimeArgumentHandle or an open generic type.
throw new jlIllegalArgumentException(x.Message);
}
}
#endif // FIRST_PASS
}
}
static class Class
{
public static jlClass forName0(string name, bool initialize, jlClassLoader loader)
{
#if FIRST_PASS
return null;
#else
//Console.WriteLine("forName: " + name + ", loader = " + loader);
TypeWrapper tw = null;
if (name.IndexOf(',') > 0)
{
// we essentially require full trust before allowing arbitrary types to be loaded,
// hence we do the "createClassLoader" permission check
jlSecurityManager sm = jlSystem.getSecurityManager();
if (sm != null)
sm.checkPermission(new jlRuntimePermission("createClassLoader"));
Type type = Type.GetType(name);
if (type != null)
{
tw = ClassLoaderWrapper.GetWrapperFromType(type);
}
if (tw == null)
{
throw new jlClassNotFoundException(name);
}
}
else
{
try
{
ClassLoaderWrapper classLoaderWrapper = ClassLoaderWrapper.GetClassLoaderWrapper(loader);
tw = classLoaderWrapper.LoadClassByDottedName(name);
}
catch (RetargetableJavaException x)
{
throw x.ToJava();
}
}
if (initialize && !tw.IsArray)
{
try
{
tw.Finish();
}
catch (RetargetableJavaException x)
{
throw x.ToJava();
}
tw.RunClassInit();
}
return tw.ClassObject;
#endif
}
public static bool isInstance(jlClass thisClass, object obj)
{
return TypeWrapper.FromClass(thisClass).IsInstance(obj);
}
public static bool isAssignableFrom(jlClass thisClass, jlClass otherClass)
{
#if !FIRST_PASS
if (otherClass == null)
{
throw new jlNullPointerException();
}
#endif
return TypeWrapper.FromClass(otherClass).IsAssignableTo(TypeWrapper.FromClass(thisClass));
}
public static bool isInterface(jlClass thisClass)
{
return TypeWrapper.FromClass(thisClass).IsInterface;
}
public static bool isArray(jlClass thisClass)
{
return TypeWrapper.FromClass(thisClass).IsArray;
}
public static bool isPrimitive(jlClass thisClass)
{
return TypeWrapper.FromClass(thisClass).IsPrimitive;
}
public static string getName0(jlClass thisClass)
{
TypeWrapper tw = TypeWrapper.FromClass(thisClass);
if (tw.IsPrimitive)
{
if (tw == PrimitiveTypeWrapper.BYTE)
{
return "byte";
}
else if (tw == PrimitiveTypeWrapper.CHAR)
{
return "char";
}
else if (tw == PrimitiveTypeWrapper.DOUBLE)
{
return "double";
}
else if (tw == PrimitiveTypeWrapper.FLOAT)
{
return "float";
}
else if (tw == PrimitiveTypeWrapper.INT)
{
return "int";
}
else if (tw == PrimitiveTypeWrapper.LONG)
{
return "long";
}
else if (tw == PrimitiveTypeWrapper.SHORT)
{
return "short";
}
else if (tw == PrimitiveTypeWrapper.BOOLEAN)
{
return "boolean";
}
else if (tw == PrimitiveTypeWrapper.VOID)
{
return "void";
}
}
return tw.Name;
}
public static string getSigName(jlClass thisClass)
{
return TypeWrapper.FromClass(thisClass).SigName;
}
public static object getClassLoader0(jlClass thisClass)
{
return TypeWrapper.FromClass(thisClass).GetClassLoader().GetJavaClassLoader();
}
public static object getSuperclass(jlClass thisClass)
{
TypeWrapper super = TypeWrapper.FromClass(thisClass).BaseTypeWrapper;
return super != null ? super.ClassObject : null;
}
public static object getInterfaces(jlClass thisClass)
{
#if FIRST_PASS
return null;
#else
TypeWrapper[] ifaces = TypeWrapper.FromClass(thisClass).Interfaces;
jlClass[] interfaces = new jlClass[ifaces.Length];
for (int i = 0; i < ifaces.Length; i++)
{
interfaces[i] = ifaces[i].ClassObject;
}
return interfaces;
#endif
}
public static object getComponentType(jlClass thisClass)
{
TypeWrapper tw = TypeWrapper.FromClass(thisClass);
return tw.IsArray ? tw.ElementTypeWrapper.ClassObject : null;
}
public static int getModifiers(jlClass thisClass)
{
// the 0x7FFF mask comes from JVM_ACC_WRITTEN_FLAGS in hotspot\src\share\vm\utilities\accessFlags.hpp
// masking out ACC_SUPER comes from instanceKlass::compute_modifier_flags() in hotspot\src\share\vm\oops\instanceKlass.cpp
const int mask = 0x7FFF & (int)~IKVM.Attributes.Modifiers.Super;
return (int)TypeWrapper.FromClass(thisClass).ReflectiveModifiers & mask;
}
public static object[] getSigners(jlClass thisClass)
{
#if FIRST_PASS
return null;
#else
return thisClass.signers;
#endif
}
public static void setSigners(jlClass thisClass, object[] signers)
{
#if !FIRST_PASS
thisClass.signers = signers;
#endif
}
public static object[] getEnclosingMethod0(jlClass thisClass)
{
TypeWrapper tw = TypeWrapper.FromClass(thisClass);
tw.Finish();
string[] enc = tw.GetEnclosingMethod();
if (enc == null)
{
return null;
}
try
{
return new object[] { tw.GetClassLoader().LoadClassByDottedName(enc[0]).ClassObject, enc[1], enc[2] == null ? null : enc[2].Replace('.', '/') };
}
catch (RetargetableJavaException x)
{
throw x.ToJava();
}
}
public static object getDeclaringClass(jlClass thisClass)
{
try
{
TypeWrapper wrapper = TypeWrapper.FromClass(thisClass);
wrapper.Finish();
TypeWrapper decl = wrapper.DeclaringTypeWrapper;
if (decl == null)
{
return null;
}
if (!decl.IsAccessibleFrom(wrapper))
{
throw new IllegalAccessError(string.Format("tried to access class {0} from class {1}", decl.Name, wrapper.Name));
}
decl.Finish();
if (SystemArray.IndexOf(decl.InnerClasses, wrapper) == -1)
{
throw new IncompatibleClassChangeError(string.Format("{0} and {1} disagree on InnerClasses attribute", decl.Name, wrapper.Name));
}
return decl.ClassObject;
}
catch (RetargetableJavaException x)
{
throw x.ToJava();
}
}
public static ProtectionDomain getProtectionDomain0(jlClass thisClass)
{
#if FIRST_PASS
return null;
#else
TypeWrapper wrapper = TypeWrapper.FromClass(thisClass);
while (wrapper.IsArray)
{
wrapper = wrapper.ElementTypeWrapper;
}
ProtectionDomain pd = wrapper.ClassObject.pd;
if (pd == null)
{
// The protection domain for statically compiled code is created lazily (not at java.lang.Class creation time),
// to work around boot strap issues.
AssemblyClassLoader acl = wrapper.GetClassLoader() as AssemblyClassLoader;
if (acl != null)
{
pd = (ProtectionDomain)acl.GetProtectionDomain();
}
}
return pd;
#endif
}
public static void setProtectionDomain0(jlClass thisClass, ProtectionDomain pd)
{
#if !FIRST_PASS
thisClass.pd = pd;
#endif
}
public static object getPrimitiveClass(string name)
{
// note that this method isn't used anymore (because it is an intrinsic (during core class library compilation))
// it still remains for compat because it might be invoked through reflection by evil code
switch (name)
{
case "byte":
return PrimitiveTypeWrapper.BYTE.ClassObject;
case "char":
return PrimitiveTypeWrapper.CHAR.ClassObject;
case "double":
return PrimitiveTypeWrapper.DOUBLE.ClassObject;
case "float":
return PrimitiveTypeWrapper.FLOAT.ClassObject;
case "int":
return PrimitiveTypeWrapper.INT.ClassObject;
case "long":
return PrimitiveTypeWrapper.LONG.ClassObject;
case "short":
return PrimitiveTypeWrapper.SHORT.ClassObject;
case "boolean":
return PrimitiveTypeWrapper.BOOLEAN.ClassObject;
case "void":
return PrimitiveTypeWrapper.VOID.ClassObject;
default:
throw new ArgumentException(name);
}
}
public static string getGenericSignature(jlClass thisClass)
{
TypeWrapper tw = TypeWrapper.FromClass(thisClass);
tw.Finish();
return tw.GetGenericSignature();
}
internal static object AnnotationsToMap(object[] objAnn)
{
#if FIRST_PASS
return null;
#else
global::java.util.LinkedHashMap map = new global::java.util.LinkedHashMap();
if (objAnn != null)
{
foreach (object obj in objAnn)
{
Annotation a = obj as Annotation;
if (a != null)
{
map.put(a.annotationType(), FreezeOrWrapAttribute(a));
}
}
}
return map;
#endif
}
#if !FIRST_PASS
internal static Annotation FreezeOrWrapAttribute(Annotation ann)
{
global::ikvm.@internal.AnnotationAttributeBase attr = ann as global::ikvm.@internal.AnnotationAttributeBase;
if (attr != null)
{
#if DONT_WRAP_ANNOTATION_ATTRIBUTES
attr.freeze();
#else
// freeze to make sure the defaults are set
attr.freeze();
ann = global::sun.reflect.annotation.AnnotationParser.annotationForMap(attr.annotationType(), attr.getValues());
#endif
}
return ann;
}
#endif
public static object getDeclaredAnnotationsImpl(jlClass thisClass)
{
#if FIRST_PASS
return null;
#else
TypeWrapper wrapper = TypeWrapper.FromClass(thisClass);
try
{
wrapper.Finish();
}
catch (RetargetableJavaException x)
{
throw x.ToJava();
}
return AnnotationsToMap(wrapper.GetDeclaredAnnotations());
#endif
}
public static object getDeclaredFields0(jlClass thisClass, bool publicOnly)
{
#if FIRST_PASS
return null;
#else
Profiler.Enter("Class.getDeclaredFields0");
try
{
TypeWrapper wrapper = TypeWrapper.FromClass(thisClass);
// we need to finish the type otherwise all fields will not be in the field map yet
wrapper.Finish();
FieldWrapper[] fields = wrapper.GetFields();
List<jlrField> list = new List<jlrField>();
for (int i = 0; i < fields.Length; i++)
{
if (fields[i].IsHideFromReflection)
{
// skip
}
else if (publicOnly && !fields[i].IsPublic)
{
// caller is only asking for public field, so we don't return this non-public field
}
else
{
list.Add((jlrField)fields[i].ToField(false, i));
}
}
return list.ToArray();
}
catch (RetargetableJavaException x)
{
throw x.ToJava();
}
finally
{
Profiler.Leave("Class.getDeclaredFields0");
}
#endif
}
public static object getDeclaredMethods0(jlClass thisClass, bool publicOnly)
{
#if FIRST_PASS
return null;
#else
Profiler.Enter("Class.getDeclaredMethods0");
try
{
TypeWrapper wrapper = TypeWrapper.FromClass(thisClass);
wrapper.Finish();
if (wrapper.HasVerifyError)
{
// TODO we should get the message from somewhere
throw new VerifyError();
}
if (wrapper.HasClassFormatError)
{
// TODO we should get the message from somewhere
throw new ClassFormatError(wrapper.Name);
}
MethodWrapper[] methods = wrapper.GetMethods();
List<jlrMethod> list = new List<jlrMethod>();
for (int i = 0; i < methods.Length; i++)
{
// we don't want to expose "hideFromReflection" methods (one reason is that it would
// mess up the serialVersionUID computation)
if (!methods[i].IsHideFromReflection
&& methods[i].Name != "<clinit>" && methods[i].Name != "<init>"
&& (!publicOnly || methods[i].IsPublic))
{
list.Add((jlrMethod)methods[i].ToMethodOrConstructor(false));
}
}
return list.ToArray();
}
catch (RetargetableJavaException x)
{
throw x.ToJava();
}
finally
{
Profiler.Leave("Class.getDeclaredMethods0");
}
#endif
}
public static object getDeclaredConstructors0(jlClass thisClass, bool publicOnly)
{
#if FIRST_PASS
return null;
#else
Profiler.Enter("Class.getDeclaredConstructors0");
try
{
TypeWrapper wrapper = TypeWrapper.FromClass(thisClass);
wrapper.Finish();
if (wrapper.HasVerifyError)
{
// TODO we should get the message from somewhere
throw new VerifyError();
}
if (wrapper.HasClassFormatError)
{
// TODO we should get the message from somewhere
throw new ClassFormatError(wrapper.Name);
}
MethodWrapper[] methods = wrapper.GetMethods();
List<jlrConstructor> list = new List<jlrConstructor>();
for (int i = 0; i < methods.Length; i++)
{
// we don't want to expose "hideFromReflection" methods (one reason is that it would
// mess up the serialVersionUID computation)
if (!methods[i].IsHideFromReflection
&& methods[i].Name == "<init>"
&& (!publicOnly || methods[i].IsPublic))
{
list.Add((jlrConstructor)methods[i].ToMethodOrConstructor(false));
}
}
return list.ToArray();
}
catch (RetargetableJavaException x)
{
throw x.ToJava();
}
finally
{
Profiler.Leave("Class.getDeclaredConstructors0");
}
#endif
}
public static object getDeclaredClasses0(jlClass thisClass)
{
#if FIRST_PASS
return null;
#else
try
{
TypeWrapper wrapper = TypeWrapper.FromClass(thisClass);
// NOTE to get at the InnerClasses we need to finish the type
wrapper.Finish();
TypeWrapper[] wrappers = wrapper.InnerClasses;
jlClass[] innerclasses = new jlClass[wrappers.Length];
for (int i = 0; i < innerclasses.Length; i++)
{
if (wrappers[i].IsUnloadable)
{
throw new jlNoClassDefFoundError(wrappers[i].Name);
}
if (!wrappers[i].IsAccessibleFrom(wrapper))
{
throw new IllegalAccessError(string.Format("tried to access class {0} from class {1}", wrappers[i].Name, wrapper.Name));
}
wrappers[i].Finish();
innerclasses[i] = wrappers[i].ClassObject;
}
return innerclasses;
}
catch (RetargetableJavaException x)
{
throw x.ToJava();
}
#endif
}
public static bool desiredAssertionStatus0(jlClass clazz)
{
return IKVM.Runtime.Assertions.IsEnabled(TypeWrapper.FromClass(clazz));
}
}
static class ClassLoader
{
public static object defineClass0(jlClassLoader thisClassLoader, string name, byte[] b, int off, int len, object pd)
{
return defineClass1(thisClassLoader, name, b, off, len, pd, null);
}
public static object defineClass1(jlClassLoader thisClassLoader, string name, byte[] b, int off, int len, object pd, string source)
{
// it appears the source argument is only used for trace messages in HotSpot. We'll just ignore it for now.
Profiler.Enter("ClassLoader.defineClass");
try
{
try
{
ClassLoaderWrapper classLoaderWrapper = ClassLoaderWrapper.GetClassLoaderWrapper(thisClassLoader);
ClassFileParseOptions cfp = ClassFileParseOptions.LineNumberTable;
if (classLoaderWrapper.EmitDebugInfo)
{
cfp |= ClassFileParseOptions.LocalVariableTable;
}
if (classLoaderWrapper.RelaxedClassNameValidation)
{
cfp |= ClassFileParseOptions.RelaxedClassNameValidation;
}
ClassFile classFile = new ClassFile(b, off, len, name, cfp);
if (name != null && classFile.Name != name)
{
#if !FIRST_PASS
throw new jlNoClassDefFoundError(name + " (wrong name: " + classFile.Name + ")");
#endif
}
TypeWrapper type = classLoaderWrapper.DefineClass(classFile, pd);
return type.ClassObject;
}
catch (RetargetableJavaException x)
{
throw x.ToJava();
}
}
finally
{
Profiler.Leave("ClassLoader.defineClass");
}
}
public static object defineClass2(jlClassLoader thisClassLoader, string name, jnByteBuffer bb, int off, int len, ProtectionDomain pd, string source)
{
#if FIRST_PASS
return null;
#else
byte[] buf = new byte[bb.remaining()];
bb.get(buf);
return defineClass1(thisClassLoader, name, buf, 0, buf.Length, pd, source);
#endif
}
public static void resolveClass0(jlClassLoader thisClassLoader, object clazz)
{
// no-op
}
public static object findBootstrapClass(jlClassLoader thisClassLoader, string name)
{
#if FIRST_PASS
return null;
#else
TypeWrapper tw;
try
{
tw = ClassLoaderWrapper.GetBootstrapClassLoader().LoadClassByDottedNameFast(name);
}
catch (RetargetableJavaException x)
{
throw x.ToJava();
}
return tw != null ? tw.ClassObject : null;
#endif
}
public static object findLoadedClass0(jlClassLoader thisClassLoader, string name)
{
if (name == null)
{
return null;
}
ClassLoaderWrapper loader = ClassLoaderWrapper.GetClassLoaderWrapper(thisClassLoader);
TypeWrapper tw = loader.GetLoadedClass(name);
return tw != null ? tw.ClassObject : null;
}
internal static class NativeLibrary
{
public static void load(object thisNativeLibrary, string name)
{
#if !FIRST_PASS
if (VirtualFileSystem.IsVirtualFS(name))
{
// we fake success for native libraries loaded from VFS
((global::java.lang.ClassLoader.NativeLibrary)thisNativeLibrary).handle = -1;
}
else
{
doLoad(thisNativeLibrary, name);
}
#endif
}
#if !FIRST_PASS
// we don't want to inline this method, because that would needlessly cause IKVM.Runtime.JNI.dll to be loaded when loading a fake native library from VFS
[MethodImpl(MethodImplOptions.NoInlining)]
[global::System.Security.SecuritySafeCritical]
private static void doLoad(object thisNativeLibrary, string name)
{
global::java.lang.ClassLoader.NativeLibrary lib = (global::java.lang.ClassLoader.NativeLibrary)thisNativeLibrary;
lib.handle = IKVM.Runtime.JniHelper.LoadLibrary(name, TypeWrapper.FromClass(lib.fromClass).GetClassLoader());
}
#endif
public static long find(object thisNativeLibrary, string name)
{
// TODO
throw new NotImplementedException();
}
[global::System.Security.SecuritySafeCritical]
public static void unload(object thisNativeLibrary)
{
#if !FIRST_PASS
global::java.lang.ClassLoader.NativeLibrary lib = (global::java.lang.ClassLoader.NativeLibrary)thisNativeLibrary;
long handle = Interlocked.Exchange(ref lib.handle, 0);
if (handle != 0)
{
IKVM.Runtime.JniHelper.UnloadLibrary(handle, TypeWrapper.FromClass(lib.fromClass).GetClassLoader());
}
#endif
}
}
public static object retrieveDirectives()
{
return IKVM.Runtime.Assertions.RetrieveDirectives();
}
}
static class Compiler
{
public static void initialize()
{
}
public static void registerNatives()
{
}
public static bool compileClass(object clazz)
{
return false;
}
public static bool compileClasses(string str)
{
return false;
}
public static object command(object any)
{
return null;
}
public static void enable()
{
}
public static void disable()
{
}
}
static class Double
{
public static long doubleToRawLongBits(double value)
{
IKVM.Runtime.DoubleConverter converter = new IKVM.Runtime.DoubleConverter();
return IKVM.Runtime.DoubleConverter.ToLong(value, ref converter);
}
public static double longBitsToDouble(long bits)
{
IKVM.Runtime.DoubleConverter converter = new IKVM.Runtime.DoubleConverter();
return IKVM.Runtime.DoubleConverter.ToDouble(bits, ref converter);
}
}
static class Float
{
public static int floatToRawIntBits(float value)
{
IKVM.Runtime.FloatConverter converter = new IKVM.Runtime.FloatConverter();
return IKVM.Runtime.FloatConverter.ToInt(value, ref converter);
}
public static float intBitsToFloat(int bits)
{
IKVM.Runtime.FloatConverter converter = new IKVM.Runtime.FloatConverter();
return IKVM.Runtime.FloatConverter.ToFloat(bits, ref converter);
}
}
static class Package
{
public static string getSystemPackage0(string name)
{
// this method is not implemented because we redirect Package.getSystemPackage() to our implementation in LangHelper
throw new NotImplementedException();
}
public static string[] getSystemPackages0()
{
// this method is not implemented because we redirect Package.getSystemPackages() to our implementation in LangHelper
throw new NotImplementedException();
}
}
static class ProcessEnvironment
{
public static string environmentBlock()
{
StringBuilder sb = new StringBuilder();
foreach (global::System.Collections.DictionaryEntry de in Environment.GetEnvironmentVariables())
{
sb.Append(de.Key).Append('=').Append(de.Value).Append('\u0000');
}
if (sb.Length == 0)
{
sb.Append('\u0000');
}
sb.Append('\u0000');
return sb.ToString();
}
}
static class Runtime
{
public static int availableProcessors(object thisRuntime)
{
return Environment.ProcessorCount;
}
public static long freeMemory(object thisRuntime)
{
// TODO figure out if there is anything meaningful we can return here
return 10 * 1024 * 1024;
}
public static long totalMemory(object thisRuntime)
{
// NOTE this really is a bogus number, but we have to return something
return GC.GetTotalMemory(false) + freeMemory(thisRuntime);
}
public static long maxMemory(object thisRuntime)
{
// spec says: If there is no inherent limit then the value Long.MAX_VALUE will be returned.
return Int64.MaxValue;
}
public static void gc(object thisRuntime)
{
GC.Collect();
}
public static void traceInstructions(object thisRuntime, bool on)
{
}
public static void traceMethodCalls(object thisRuntime, bool on)
{
}
public static void runFinalization0()
{
GC.WaitForPendingFinalizers();
}
}
static class SecurityManager
{
// this field is set by code in the JNI assembly itself,
// to prevent having to load the JNI assembly when it isn't used.
internal static volatile Assembly jniAssembly;
public static jlClass[] getClassContext(object thisSecurityManager)
{
#if FIRST_PASS
return null;
#else
List<jlClass> stack = new List<jlClass>();
StackTrace trace = new StackTrace();
for (int i = 0; i < trace.FrameCount; i++)
{
StackFrame frame = trace.GetFrame(i);
MethodBase method = frame.GetMethod();
Type type = method.DeclaringType;
// NOTE these checks should be the same as the ones in Reflection.getCallerClass
if (IKVM.NativeCode.sun.reflect.Reflection.IsHideFromJava(method)
|| type == null
|| type.Assembly == typeof(object).Assembly
|| type.Assembly == typeof(SecurityManager).Assembly
|| type.Assembly == jniAssembly
|| type == typeof(jlrConstructor)
|| type == typeof(jlrMethod))
{
continue;
}
if (type == typeof(jlSecurityManager))
{
continue;
}
stack.Add(ClassLoaderWrapper.GetWrapperFromType(type).ClassObject);
}
return stack.ToArray();
#endif
}
public static object currentClassLoader0(object thisSecurityManager)
{
jlClass currentClass = currentLoadedClass0(thisSecurityManager);
if (currentClass != null)
{
return TypeWrapper.FromClass(currentClass).GetClassLoader().GetJavaClassLoader();
}
return null;
}
public static int classDepth(object thisSecurityManager, string name)
{
throw new NotImplementedException();
}
public static int classLoaderDepth0(object thisSecurityManager)
{
throw new NotImplementedException();
}
public static jlClass currentLoadedClass0(object thisSecurityManager)
{
throw new NotImplementedException();
}
}
static class StrictMath
{
public static double sin(double d)
{
#if FIRST_PASS
return 0;
#else
return global::ikvm.@internal.JMath.sin(d);
#endif
}
public static double cos(double d)
{
#if FIRST_PASS
return 0;
#else
return global::ikvm.@internal.JMath.cos(d);
#endif
}
public static double tan(double d)
{
return fdlibm.tan(d);
}
public static double asin(double d)
{
#if FIRST_PASS
return 0;
#else
return global::ikvm.@internal.JMath.asin(d);
#endif
}
public static double acos(double d)
{
#if FIRST_PASS
return 0;
#else
return global::ikvm.@internal.JMath.acos(d);
#endif
}
public static double atan(double d)
{
#if FIRST_PASS
return 0;
#else
return global::ikvm.@internal.JMath.atan(d);
#endif
}
public static double exp(double d)
{
#if FIRST_PASS
return 0;
#else
return global::ikvm.@internal.JMath.exp(d);
#endif
}
public static double log(double d)
{
// FPU behavior is correct
return Math.Log(d);
}
public static double log10(double d)
{
// FPU behavior is correct
return Math.Log10(d);
}
public static double sqrt(double d)
{
// FPU behavior is correct
return Math.Sqrt(d);
}
public static double cbrt(double d)
{
return fdlibm.cbrt(d);
}
public static double IEEEremainder(double f1, double f2)
{
#if FIRST_PASS
return 0;
#else
return global::ikvm.@internal.JMath.IEEEremainder(f1, f2);
#endif
}
public static double ceil(double d)
{
#if FIRST_PASS
return 0;
#else
return global::ikvm.@internal.JMath.ceil(d);
#endif
}
public static double floor(double d)
{
return fdlibm.floor(d);
}
public static double atan2(double y, double x)
{
#if FIRST_PASS
return 0;
#else
return global::ikvm.@internal.JMath.atan2(y, x);
#endif
}
public static double pow(double x, double y)
{
return fdlibm.__ieee754_pow(x, y);
}
public static double sinh(double d)
{
return Math.Sinh(d);
}
public static double cosh(double d)
{
return Math.Cosh(d);
}
public static double tanh(double d)
{
return Math.Tanh(d);
}
public static double rint(double d)
{
#if FIRST_PASS
return 0;
#else
return global::ikvm.@internal.JMath.rint(d);
#endif
}
public static double hypot(double a, double b)
{
return fdlibm.__ieee754_hypot(a, b);
}
public static double expm1(double d)
{
return fdlibm.expm1(d);
}
public static double log1p(double d)
{
return fdlibm.log1p(d);
}
}
static class System
{
public static void arraycopy(object src, int srcPos, object dest, int destPos, int length)
{
IKVM.Runtime.ByteCodeHelper.arraycopy(src, srcPos, dest, destPos, length);
}
}
static class Thread
{
private static readonly object mainThreadGroup;
#if !FIRST_PASS
static Thread()
{
mainThreadGroup = new jlThreadGroup(jlThreadGroup.createRootGroup(), "main");
}
#endif
public static object getMainThreadGroup()
{
return mainThreadGroup;
}
// this is called from JniInterface.cs
internal static void WaitUntilLastJniThread()
{
#if !FIRST_PASS
int count = jlThread.currentThread().isDaemon() ? 0 : 1;
while (Interlocked.CompareExchange(ref jlThread.nonDaemonCount[0], 0, 0) > count)
{
SystemThreadingThread.Sleep(1);
}
#endif
}
// this is called from JniInterface.cs
internal static void AttachThreadFromJni(object threadGroup)
{
#if !FIRST_PASS
if (threadGroup == null)
{
threadGroup = mainThreadGroup;
}
if (jlThread.current == null)
{
new jlThread((jlThreadGroup)threadGroup);
}
#endif
}
public static jlStackTraceElement[] getStackTrace(StackTrace stack)
{
#if FIRST_PASS
return null;
#else
List<jlStackTraceElement> stackTrace = new List<jlStackTraceElement>();
ExceptionHelper.ExceptionInfoHelper.Append(stackTrace, stack, 0, true);
return stackTrace.ToArray();
#endif
}
public static object getThreads()
{
#if FIRST_PASS
return null;
#else
return global::java.security.AccessController.doPrivileged(global::ikvm.runtime.Delegates.toPrivilegedAction(delegate
{
jlThreadGroup root = (jlThreadGroup)mainThreadGroup;
for (; ; )
{
jlThread[] threads = new jlThread[root.activeCount()];
if (root.enumerate(threads) == threads.Length)
{
return threads;
}
}
}));
#endif
}
}
static class ProcessImpl
{
public static string mapVfsExecutable(string path)
{
if (VirtualFileSystem.IsVirtualFS(path))
{
return VirtualFileSystem.MapExecutable(path);
}
return path;
}
public static int parseCommandString(string cmdstr)
{
int pos = cmdstr.IndexOf(' ');
if (pos == -1)
{
return cmdstr.Length;
}
if (cmdstr[0] == '"')
{
int close = cmdstr.IndexOf('"', 1);
return close == -1 ? cmdstr.Length : close + 1;
}
if (Environment.OSVersion.Platform != PlatformID.Win32NT)
{
return pos;
}
IList<string> path = null;
for (; ; )
{
string str = cmdstr.Substring(0, pos);
if (global::System.IO.Path.IsPathRooted(str))
{
if (Exists(str))
{
return pos;
}
}
else
{
if (path == null)
{
path = GetSearchPath();
}
foreach (string p in path)
{
if (Exists(global::System.IO.Path.Combine(p, str)))
{
return pos;
}
}
}
if (pos == cmdstr.Length)
{
return cmdstr.IndexOf(' ');
}
pos = cmdstr.IndexOf(' ', pos + 1);
if (pos == -1)
{
pos = cmdstr.Length;
}
}
}
private static List<string> GetSearchPath()
{
List<string> list = new List<string>();
list.Add(global::System.IO.Path.GetDirectoryName(global::System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName));
list.Add(Environment.CurrentDirectory);
list.Add(Environment.SystemDirectory);
string windir = global::System.IO.Path.GetDirectoryName(Environment.SystemDirectory);
list.Add(global::System.IO.Path.Combine(windir, "System"));
list.Add(windir);
string path = Environment.GetEnvironmentVariable("PATH");
if (path != null)
{
foreach (string p in path.Split(global::System.IO.Path.PathSeparator))
{
list.Add(p);
}
}
return list;
}
private static bool Exists(string file)
{
try
{
if (global::System.IO.File.Exists(file))
{
return true;
}
else if (global::System.IO.Directory.Exists(file))
{
return false;
}
else if (file.IndexOf('.') == -1 && global::System.IO.File.Exists(file + ".exe"))
{
return true;
}
else
{
return false;
}
}
catch
{
return false;
}
}
}
namespace reflect
{
static class Proxy
{
public static object defineClass0(jlClassLoader classLoader, string name, byte[] b, int off, int len)
{
return ClassLoader.defineClass1(classLoader, name, b, off, len, null, null);
}
public static jlClass getPrecompiledProxy(jlClassLoader classLoader, string proxyName, jlClass[] interfaces)
{
AssemblyClassLoader acl = ClassLoaderWrapper.GetClassLoaderWrapper(classLoader) as AssemblyClassLoader;
if (acl == null)
{
return null;
}
TypeWrapper[] wrappers = new TypeWrapper[interfaces.Length];
for (int i = 0; i < wrappers.Length; i++)
{
wrappers[i] = TypeWrapper.FromClass(interfaces[i]);
}
// TODO support multi assembly class loaders
Type type = acl.MainAssembly.GetType(DynamicClassLoader.GetProxyName(wrappers));
if (type == null)
{
return null;
}
TypeWrapper tw = CompiledTypeWrapper.newInstance(proxyName, type);
TypeWrapper tw2 = acl.RegisterInitiatingLoader(tw);
if (tw != tw2)
{
return null;
}
TypeWrapper[] wrappers2 = tw.Interfaces;
if (wrappers.Length != wrappers.Length)
{
return null;
}
for (int i = 0; i < wrappers.Length; i++)
{
if (wrappers[i] != wrappers2[i])
{
return null;
}
}
return tw.ClassObject;
}
}
static class Field
{
public static object getDeclaredAnnotationsImpl(object thisField)
{
FieldWrapper fw = FieldWrapper.FromField(thisField);
return Class.AnnotationsToMap(fw.DeclaringType.GetFieldAnnotations(fw));
}
}
static class Method
{
public static object getDeclaredAnnotationsImpl(object methodOrConstructor)
{
MethodWrapper mw = MethodWrapper.FromMethodOrConstructor(methodOrConstructor);
return Class.AnnotationsToMap(mw.DeclaringType.GetMethodAnnotations(mw));
}
public static object[][] getParameterAnnotationsImpl(object methodOrConstructor)
{
#if FIRST_PASS
return null;
#else
MethodWrapper mw = MethodWrapper.FromMethodOrConstructor(methodOrConstructor);
object[][] objAnn = mw.DeclaringType.GetParameterAnnotations(mw);
if (objAnn == null)
{
return null;
}
Annotation[][] ann = new Annotation[objAnn.Length][];
for (int i = 0; i < ann.Length; i++)
{
List<Annotation> list = new List<Annotation>();
foreach (object obj in objAnn[i])
{
Annotation a = obj as Annotation;
if (a != null)
{
list.Add(Class.FreezeOrWrapAttribute(a));
}
}
ann[i] = list.ToArray();
}
return ann;
#endif
}
public static object getDefaultValue(object thisMethod)
{
MethodWrapper mw = MethodWrapper.FromMethodOrConstructor(thisMethod);
return mw.DeclaringType.GetAnnotationDefault(mw);
}
}
}
}
namespace net
{
static class DatagramPacket
{
public static void init()
{
}
}
static class InetAddress
{
public static void init()
{
}
#if !FIRST_PASS
internal static jnInetAddress ConvertIPAddress(System.Net.IPAddress address, string hostname)
{
if (address.IsIPv6LinkLocal || address.IsIPv6SiteLocal)
{
return jnInet6Address.getByAddress(hostname, address.GetAddressBytes(), (int)address.ScopeId);
}
else
{
return jnInetAddress.getByAddress(hostname, address.GetAddressBytes());
}
}
#endif
}
static class InetAddressImplFactory
{
private static readonly bool ipv6supported = Init();
private static bool Init()
{
string env = IKVM.Internal.JVM.SafeGetEnvironmentVariable("IKVM_IPV6");
int val;
if (env != null && Int32.TryParse(env, out val))
{
return (val & 1) != 0;
}
// On Linux we can't bind both an IPv4 and IPv6 to the same port, so we have to disable IPv6 until we have a dual-stack implementation.
// Mono on Windows doesn't appear to support IPv6 either (Mono on Linux does).
return Type.GetType("Mono.Runtime") == null
&& Environment.OSVersion.Platform == PlatformID.Win32NT
&& System.Net.Sockets.Socket.OSSupportsIPv6;
}
public static bool isIPv6Supported()
{
return ipv6supported;
}
}
static class Inet4Address
{
public static void init()
{
}
}
static class Inet4AddressImpl
{
public static string getLocalHostName(object thisInet4AddressImpl)
{
#if FIRST_PASS
return null;
#else
try
{
return System.Net.Dns.GetHostName();
}
catch (System.Net.Sockets.SocketException)
{
}
catch (System.Security.SecurityException)
{
}
return "localhost";
#endif
}
public static object lookupAllHostAddr(object thisInet4AddressImpl, string hostname)
{
#if FIRST_PASS
return null;
#else
try
{
System.Net.IPAddress[] addr = System.Net.Dns.GetHostAddresses(hostname);
List<jnInetAddress> addresses = new List<jnInetAddress>();
for (int i = 0; i < addr.Length; i++)
{
byte[] b = addr[i].GetAddressBytes();
if (b.Length == 4)
{
addresses.Add(jnInetAddress.getByAddress(hostname, b));
}
}
if (addresses.Count == 0)
{
throw new jnUnknownHostException(hostname);
}
return addresses.ToArray();
}
catch (System.ArgumentException x)
{
throw new jnUnknownHostException(x.Message);
}
catch (System.Net.Sockets.SocketException x)
{
throw new jnUnknownHostException(x.Message);
}
#endif
}
public static string getHostByAddr(object thisInet4AddressImpl, byte[] addr)
{
#if FIRST_PASS
return null;
#else
try
{
return System.Net.Dns.GetHostEntry(new System.Net.IPAddress(addr)).HostName;
}
catch (System.ArgumentException x)
{
throw new jnUnknownHostException(x.Message);
}
catch (System.Net.Sockets.SocketException x)
{
throw new jnUnknownHostException(x.Message);
}
#endif
}
public static bool isReachable0(object thisInet4AddressImpl, byte[] addr, int timeout, byte[] ifaddr, int ttl)
{
// like the JDK, we don't use Ping, but we try a TCP connection to the echo port
// (.NET 2.0 has a System.Net.NetworkInformation.Ping class, but that doesn't provide the option of binding to a specific interface)
try
{
using (System.Net.Sockets.Socket sock = new System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp))
{
if (ifaddr != null)
{
sock.Bind(new System.Net.IPEndPoint(((ifaddr[3] << 24) + (ifaddr[2] << 16) + (ifaddr[1] << 8) + ifaddr[0]) & 0xFFFFFFFFL, 0));
}
if (ttl > 0)
{
sock.SetSocketOption(System.Net.Sockets.SocketOptionLevel.IP, System.Net.Sockets.SocketOptionName.IpTimeToLive, ttl);
}
System.Net.IPEndPoint ep = new System.Net.IPEndPoint(((addr[3] << 24) + (addr[2] << 16) + (addr[1] << 8) + addr[0]) & 0xFFFFFFFFL, 7);
IAsyncResult res = sock.BeginConnect(ep, null, null);
if (res.AsyncWaitHandle.WaitOne(timeout, false))
{
try
{
sock.EndConnect(res);
return true;
}
catch (System.Net.Sockets.SocketException x)
{
const int WSAECONNREFUSED = 10061;
if (x.ErrorCode == WSAECONNREFUSED)
{
// we got back an explicit "connection refused", that means the host was reachable.
return true;
}
}
}
}
}
catch (System.Net.Sockets.SocketException)
{
}
return false;
}
}
static class Inet6Address
{
public static void init()
{
}
}
static class Inet6AddressImpl
{
public static string getLocalHostName(object thisInet6AddressImpl)
{
#if FIRST_PASS
return null;
#else
try
{
return System.Net.Dns.GetHostName();
}
catch (System.Net.Sockets.SocketException x)
{
throw new jnUnknownHostException(x.Message);
}
#endif