2007-05-28 14:15:23 +04:00
/ *
2009-06-06 16:32:47 +04:00
Copyright ( C ) 2007 , 2008 , 2009 Jeroen Frijters
Copyright ( C ) 2009 Volker Berlin ( i - net software )
2007-05-28 14:15:23 +04:00
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 ;
2007-11-26 14:01:29 +03:00
using System.Collections.Generic ;
2007-06-09 12:33:09 +04:00
using System.Globalization ;
using System.Reflection ;
2007-09-24 15:57:00 +04:00
using System.Reflection.Emit ;
2007-06-09 12:33:09 +04:00
using System.Runtime.CompilerServices ;
using System.Runtime.Serialization ;
using System.Text ;
using System.Threading ;
2009-06-10 08:40:00 +04:00
using System.Runtime.InteropServices ;
2007-05-29 20:27:08 +04:00
using StackFrame = System . Diagnostics . StackFrame ;
2007-06-11 13:17:29 +04:00
using StackTrace = System . Diagnostics . StackTrace ;
2007-06-09 12:33:09 +04:00
using SystemArray = System . Array ;
2007-06-11 13:17:29 +04:00
using SystemDouble = System . Double ;
2007-06-20 18:15:27 +04:00
using SystemTimeZone = System . TimeZone ;
2007-06-09 12:33:09 +04:00
using SystemThreadingThread = System . Threading . Thread ;
using SystemThreadingThreadInterruptedException = System . Threading . ThreadInterruptedException ;
using SystemThreadingThreadPriority = System . Threading . ThreadPriority ;
2007-05-28 14:15:23 +04:00
using IKVM.Internal ;
#if ! FIRST_PASS
using jlClass = java . lang . Class ;
2007-06-18 13:14:59 +04:00
using jlClassLoader = java . lang . ClassLoader ;
2007-05-31 11:13:46 +04:00
using jlArrayIndexOutOfBoundsException = java . lang . ArrayIndexOutOfBoundsException ;
2007-05-28 14:15:23 +04:00
using jlClassNotFoundException = java . lang . ClassNotFoundException ;
2007-07-11 11:11:35 +04:00
using jlException = java . lang . Exception ;
2007-05-29 20:27:08 +04:00
using jlIllegalAccessException = java . lang . IllegalAccessException ;
using jlIllegalArgumentException = java . lang . IllegalArgumentException ;
2007-06-05 10:57:18 +04:00
using jlInterruptedException = java . lang . InterruptedException ;
2007-09-24 15:57:00 +04:00
using jlInternalError = java . lang . InternalError ;
2007-05-31 11:13:46 +04:00
using jlNegativeArraySizeException = java . lang . NegativeArraySizeException ;
2007-05-28 14:15:23 +04:00
using jlNoClassDefFoundError = java . lang . NoClassDefFoundError ;
2007-05-31 11:13:46 +04:00
using jlNullPointerException = java . lang . NullPointerException ;
2007-06-05 10:57:18 +04:00
using jlRunnable = java . lang . Runnable ;
2007-07-11 11:11:35 +04:00
using jlRuntimeException = java . lang . RuntimeException ;
2007-05-28 14:15:23 +04:00
using jlSecurityManager = java . lang . SecurityManager ;
using jlStackTraceElement = java . lang . StackTraceElement ;
using jlSystem = java . lang . System ;
2007-06-05 10:57:18 +04:00
using jlThread = java . lang . Thread ;
using jlThreadDeath = java . lang . ThreadDeath ;
using jlThreadGroup = java . lang . ThreadGroup ;
2007-05-28 14:15:23 +04:00
using jlRuntimePermission = java . lang . RuntimePermission ;
2007-05-29 20:27:08 +04:00
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 ;
2007-05-28 14:15:23 +04:00
using jlrConstructor = java . lang . reflect . Constructor ;
using jlrMethod = java . lang . reflect . Method ;
using jlrField = java . lang . reflect . Field ;
2007-05-29 20:27:08 +04:00
using jlrModifier = java . lang . reflect . Modifier ;
2007-08-07 11:44:42 +04:00
using jlrAccessibleObject = java . lang . reflect . AccessibleObject ;
2007-09-24 15:57:00 +04:00
using jlrInvocationTargetException = java . lang . reflect . InvocationTargetException ;
2007-05-28 14:15:23 +04:00
using ProtectionDomain = java . security . ProtectionDomain ;
using srMethodAccessor = sun . reflect . MethodAccessor ;
using srConstructorAccessor = sun . reflect . ConstructorAccessor ;
2007-05-29 20:27:08 +04:00
using srFieldAccessor = sun . reflect . FieldAccessor ;
2007-05-28 14:15:23 +04:00
using srLangReflectAccess = sun . reflect . LangReflectAccess ;
2007-05-29 20:27:08 +04:00
using srReflection = sun . reflect . Reflection ;
2007-05-28 14:15:23 +04:00
using srReflectionFactory = sun . reflect . ReflectionFactory ;
using jnByteBuffer = java . nio . ByteBuffer ;
using StubGenerator = ikvm . @internal . stubgen . StubGenerator ;
using Annotation = java . lang . annotation . Annotation ;
2007-06-09 12:33:09 +04:00
using smJavaIOAccess = sun . misc . JavaIOAccess ;
2007-06-12 16:54:20 +04:00
using smLauncher = sun . misc . Launcher ;
2007-06-09 12:33:09 +04:00
using smSharedSecrets = sun . misc . SharedSecrets ;
2007-08-07 11:44:42 +04:00
using smVM = sun . misc . VM ;
2007-06-09 12:33:09 +04:00
using jiConsole = java . io . Console ;
2007-06-19 08:50:45 +04:00
using jiIOException = java . io . IOException ;
using jiFile = java . io . File ;
2007-09-24 15:57:00 +04:00
using jiObjectStreamField = java . io . ObjectStreamField ;
2007-06-09 12:33:09 +04:00
using jnCharset = java . nio . charset . Charset ;
using juProperties = java . util . Properties ;
using irUtil = ikvm . runtime . Util ;
2007-09-24 15:57:00 +04:00
using iiFieldReflectorBase = ikvm . @internal . FieldReflectorBase ;
2007-06-27 10:14:54 +04:00
using juzZipFile = java . util . zip . ZipFile ;
using juzZipEntry = java . util . zip . ZipEntry ;
2007-07-12 12:40:32 +04:00
using juEnumeration = java . util . Enumeration ;
2007-06-27 10:14:54 +04:00
using jiInputStream = java . io . InputStream ;
2007-07-11 11:11:35 +04:00
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 ;
2007-07-12 12:40:32 +04:00
using jnUnknownHostException = java . net . UnknownHostException ;
using jnInetAddress = java . net . InetAddress ;
2007-07-24 11:52:24 +04:00
using jnInet4Address = java . net . Inet4Address ;
using jnInet6Address = java . net . Inet6Address ;
2007-07-24 18:33:59 +04:00
using jnNetworkInterface = java . net . NetworkInterface ;
using jnInterfaceAddress = java . net . InterfaceAddress ;
2007-08-10 17:04:21 +04:00
using ssaGetPropertyAction = sun . security . action . GetPropertyAction ;
2007-05-28 14:15:23 +04:00
#endif
2007-09-12 10:51:37 +04:00
namespace IKVM.Runtime
{
2007-12-18 14:05:30 +03:00
public static class Assertions
2007-09-12 10:51:37 +04:00
{
private static bool sysAsserts ;
private static bool userAsserts ;
private static OptionNode classes ;
private static OptionNode packages ;
private 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
2008-09-01 09:19:04 +04:00
java . lang . AssertionStatusDirectives asd = new java . lang . AssertionStatusDirectives ( ) ;
2007-09-12 10:51:37 +04:00
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 ;
}
2008-09-01 09:19:04 +04:00
asd . classes = arrStrings ;
asd . classEnabled = arrBools ;
2007-09-12 10:51:37 +04:00
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 ;
}
2008-09-01 09:19:04 +04:00
asd . packages = arrStrings ;
asd . packageEnabled = arrBools ;
asd . deflt = userAsserts ;
return asd ;
2007-09-12 10:51:37 +04:00
#endif
}
}
}
2008-09-01 08:01:36 +04:00
static class DynamicMethodUtils
{
internal static DynamicMethod Create ( string name , Type owner , bool nonPublic , Type returnType , Type [ ] paramTypes )
{
try
{
if ( owner . IsInterface )
{
// FXBUG interfaces 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 ) ;
}
}
catch ( System . Security . SecurityException )
{
2009-05-31 09:41:14 +04:00
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 ) ;
}
2008-09-01 08:01:36 +04:00
// 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
2009-05-24 09:42:20 +04:00
return new DynamicMethod ( name , returnType , paramTypes , nonPublic ) ;
2008-09-01 08:01:36 +04:00
}
}
2009-05-31 09:41:14 +04:00
private static bool RestrictedMemberAccess
{
get
{
2009-05-31 11:54:26 +04:00
try
{
new System . Security . Permissions . ReflectionPermission ( System . Security . Permissions . ReflectionPermissionFlag . RestrictedMemberAccess ) . Demand ( ) ;
return true ;
}
catch ( System . Security . SecurityException )
2009-05-31 09:41:14 +04:00
{
2009-05-31 11:54:26 +04:00
return false ;
2009-05-31 09:41:14 +04:00
}
}
}
2008-09-01 08:01:36 +04:00
}
2007-05-28 14:15:23 +04:00
namespace IKVM.NativeCode.java
{
2007-06-15 17:53:42 +04:00
namespace io
{
2007-12-18 14:05:30 +03:00
static class Console
2007-06-15 17:53:42 +04:00
{
public static string encoding ( )
{
2007-12-17 10:44:59 +03:00
int cp = 437 ;
try
{
cp = global :: System . Console . InputEncoding . CodePage ;
}
catch
{
}
if ( cp > = 874 & & cp < = 950 )
{
return "ms" + cp ;
}
return "cp" + cp ;
2007-06-15 17:53:42 +04:00
}
2007-12-17 10:44:59 +03:00
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 ) ;
2007-06-15 17:53:42 +04:00
public static bool echo ( bool on )
{
2007-12-17 10:44:59 +03:00
#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 ;
2007-06-15 17:53:42 +04:00
}
public static bool istty ( )
{
2007-12-17 10:44:59 +03:00
// 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 ;
}
2007-06-15 17:53:42 +04:00
}
}
2007-06-19 08:50:45 +04:00
2007-12-18 14:05:30 +03:00
static class FileDescriptor
2007-06-27 10:14:54 +04:00
{
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
{
return new System . IO . FileStream ( name , fileMode , fileAccess , System . IO . FileShare . ReadWrite , 1 , false ) ;
}
}
}
2007-12-18 14:05:30 +03:00
static class FileSystem
2007-06-19 08:50:45 +04:00
{
public static object getFileSystem ( )
{
#if FIRST_PASS
return null ;
#else
2007-06-27 10:14:54 +04:00
if ( JVM . IsUnix )
2007-06-19 08:50:45 +04:00
{
2009-06-25 13:18:45 +04:00
return new global :: java . io . UnixFileSystem ( ) ;
2007-06-19 08:50:45 +04:00
}
else
{
2009-06-25 13:18:45 +04:00
return new global :: java . io . Win32FileSystem ( ) ;
2007-06-19 08:50:45 +04:00
}
#endif
}
}
2007-12-18 14:05:30 +03:00
static class ObjectInputStream
2007-06-19 10:09:13 +04:00
{
public static void bytesToFloats ( byte [ ] src , int srcpos , float [ ] dst , int dstpos , int nfloats )
{
2008-09-02 08:56:19 +04:00
IKVM . Runtime . FloatConverter converter = new IKVM . Runtime . FloatConverter ( ) ;
for ( int i = 0 ; i < nfloats ; i + + )
2007-06-19 10:09:13 +04:00
{
2008-09-02 08:56:19 +04:00
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 ) ;
2007-06-19 10:09:13 +04:00
}
}
public static void bytesToDoubles ( byte [ ] src , int srcpos , double [ ] dst , int dstpos , int ndoubles )
{
2008-09-02 08:56:19 +04:00
IKVM . Runtime . DoubleConverter converter = new IKVM . Runtime . DoubleConverter ( ) ;
for ( int i = 0 ; i < ndoubles ; i + + )
2007-06-19 10:09:13 +04:00
{
2008-09-02 08:56:19 +04:00
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 ) ;
2007-06-19 10:09:13 +04:00
}
}
public static object latestUserDefinedLoader ( )
{
2009-02-12 09:25:07 +03:00
// 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 ) ;
2009-04-06 09:23:04 +04:00
for ( int i = 0 ; i < trace . FrameCount ; i + + )
2007-06-19 10:09:13 +04:00
{
2009-02-12 09:25:07 +03:00
StackFrame frame = trace . GetFrame ( i ) ;
2007-06-19 10:09:13 +04:00
MethodBase method = frame . GetMethod ( ) ;
if ( method = = null )
{
2009-04-06 09:23:04 +04:00
continue ;
2007-06-19 10:09:13 +04:00
}
Type type = method . DeclaringType ;
if ( type ! = null )
{
TypeWrapper tw = ClassLoaderWrapper . GetWrapperFromType ( type ) ;
if ( tw ! = null )
{
2007-07-02 11:11:48 +04:00
ClassLoaderWrapper classLoader = tw . GetClassLoader ( ) ;
AssemblyClassLoader acl = classLoader as AssemblyClassLoader ;
2009-02-04 10:24:44 +03:00
if ( acl = = null | | acl . GetAssembly ( tw ) ! = typeof ( object ) . Assembly )
2007-06-19 10:09:13 +04:00
{
2007-07-02 11:11:48 +04:00
object javaClassLoader = classLoader . GetJavaClassLoader ( ) ;
if ( javaClassLoader ! = null )
{
return javaClassLoader ;
}
2007-06-19 10:09:13 +04:00
}
}
}
}
2009-04-06 09:23:04 +04:00
return null ;
2007-06-19 10:09:13 +04:00
}
}
2007-12-18 14:05:30 +03:00
static class ObjectOutputStream
2007-06-19 10:09:13 +04:00
{
public static void floatsToBytes ( float [ ] src , int srcpos , byte [ ] dst , int dstpos , int nfloats )
{
2008-05-09 09:59:59 +04:00
IKVM . Runtime . FloatConverter converter = new IKVM . Runtime . FloatConverter ( ) ;
for ( int i = 0 ; i < nfloats ; i + + )
2007-06-19 10:09:13 +04:00
{
2008-05-09 09:59:59 +04:00
int v = IKVM . Runtime . FloatConverter . ToInt ( src [ srcpos + + ] , ref converter ) ;
dst [ dstpos + + ] = ( byte ) ( v > > 24 ) ;
2008-09-02 08:56:19 +04:00
dst [ dstpos + + ] = ( byte ) ( v > > 16 ) ;
dst [ dstpos + + ] = ( byte ) ( v > > 8 ) ;
dst [ dstpos + + ] = ( byte ) ( v > > 0 ) ;
2007-06-19 10:09:13 +04:00
}
}
public static void doublesToBytes ( double [ ] src , int srcpos , byte [ ] dst , int dstpos , int ndoubles )
{
2008-05-09 09:59:59 +04:00
IKVM . Runtime . DoubleConverter converter = new IKVM . Runtime . DoubleConverter ( ) ;
for ( int i = 0 ; i < ndoubles ; i + + )
2007-06-19 10:09:13 +04:00
{
2008-05-09 09:59:59 +04:00
long v = IKVM . Runtime . DoubleConverter . ToLong ( src [ srcpos + + ] , ref converter ) ;
dst [ dstpos + + ] = ( byte ) ( v > > 56 ) ;
2008-09-02 08:56:19 +04:00
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 ) ;
2007-06-19 10:09:13 +04:00
}
}
}
2007-12-19 14:28:09 +03:00
public static class IOHelpers
2007-06-19 10:09:13 +04:00
{
2007-09-24 15:57:00 +04:00
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 ) ;
2007-12-19 14:28:09 +03:00
buf [ offset + 2 ] = ( byte ) ( value > > 8 ) ;
buf [ offset + 3 ] = ( byte ) ( value > > 0 ) ;
2007-09-24 15:57:00 +04:00
}
public static void WriteFloat ( byte [ ] buf , int offset , float value )
{
2007-12-19 14:28:09 +03:00
#if ! FIRST_PASS
2008-05-09 09:59:59 +04:00
global :: java . io . Bits . putFloat ( buf , offset , value ) ;
2007-12-19 14:28:09 +03:00
#endif
2007-09-24 15:57:00 +04:00
}
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 )
{
2007-12-19 14:28:09 +03:00
#if ! FIRST_PASS
2008-05-09 09:59:59 +04:00
global :: java . io . Bits . putDouble ( buf , offset , value ) ;
2007-12-19 14:28:09 +03:00
#endif
2007-09-24 15:57:00 +04:00
}
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 )
2007-12-19 14:28:09 +03:00
+ ( buf [ offset + 2 ] < < 8 )
+ ( buf [ offset + 3 ] < < 0 ) ;
2007-09-24 15:57:00 +04:00
}
public static float ReadFloat ( byte [ ] buf , int offset )
{
2007-12-19 14:28:09 +03:00
#if FIRST_PASS
return 0 ;
#else
2007-09-24 15:57:00 +04:00
return jlFloat . intBitsToFloat ( ReadInt ( buf , offset ) ) ;
2007-12-19 14:28:09 +03:00
#endif
2007-09-24 15:57:00 +04:00
}
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 )
{
2007-12-19 14:28:09 +03:00
#if FIRST_PASS
return 0 ;
#else
2007-09-24 15:57:00 +04:00
return jlDouble . longBitsToDouble ( ReadLong ( buf , offset ) ) ;
2007-12-19 14:28:09 +03:00
#endif
2007-09-24 15:57:00 +04:00
}
2007-12-19 14:28:09 +03:00
}
2007-09-24 15:57:00 +04:00
2007-12-19 14:28:09 +03:00
static class ObjectStreamClass
{
2009-03-04 09:49:16 +03:00
private static bool runClassInit ;
2007-12-19 14:28:09 +03:00
public static void initNative ( )
{
2009-03-04 13:57:42 +03:00
#if ! FIRST_PASS
2009-03-04 09:49:16 +03:00
// HACK if we're being run from ikvmstub, don't run the static initializer
runClassInit = ! "true" . Equals ( ClassLoaderWrapper . DoPrivileged ( new global :: sun . security . action . GetPropertyAction ( "ikvm.stubgen.serialver" ) ) ) ;
2009-03-04 13:57:42 +03:00
#endif
2007-12-19 14:28:09 +03:00
}
public static bool hasStaticInitializer ( object cl )
{
TypeWrapper wrapper = TypeWrapper . FromClass ( cl ) ;
try
{
wrapper . Finish ( ) ;
}
catch ( RetargetableJavaException x )
{
throw x . ToJava ( ) ;
}
Type type = wrapper . TypeAsTBD ;
2009-03-04 16:52:05 +03:00
if ( ! type . IsArray & & type . TypeInitializer ! = null )
2007-12-19 14:28:09 +03:00
{
2009-03-04 16:52:05 +03:00
if ( runClassInit )
{
wrapper . RunClassInit ( ) ;
}
2007-12-19 14:28:09 +03:00
return ! AttributeHelper . IsHideFromJava ( type . TypeInitializer ) ;
}
return false ;
}
#if ! FIRST_PASS
2007-09-24 15:57:00 +04:00
private sealed class FastFieldReflector : iiFieldReflectorBase
{
2007-12-19 14:28:09 +03:00
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" ) ;
2007-09-24 15:57:00 +04:00
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
{
tw . Finish ( ) ;
2008-09-01 08:01:36 +04:00
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 [ ] ) } ) ;
2008-06-03 16:10:07 +04:00
CodeEmitter ilgenObjGetter = CodeEmitter . Create ( dmObjGetter ) ;
CodeEmitter ilgenPrimGetter = CodeEmitter . Create ( dmPrimGetter ) ;
CodeEmitter ilgenObjSetter = CodeEmitter . Create ( dmObjSetter ) ;
CodeEmitter ilgenPrimSetter = CodeEmitter . Create ( dmPrimSetter ) ;
2009-05-29 12:57:33 +04:00
// 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
LocalBuilder objGetterThis = ilgenObjGetter . DeclareLocal ( tw . TypeAsBaseType ) ;
LocalBuilder 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 ) ;
2007-09-24 15:57:00 +04:00
foreach ( jiObjectStreamField field in fields )
{
FieldWrapper fw = GetFieldWrapper ( field ) ;
if ( fw = = null )
{
continue ;
}
fw . ResolveField ( ) ;
TypeWrapper fieldType = fw . FieldTypeWrapper ;
fieldType . Finish ( ) ;
if ( fieldType . IsPrimitive )
{
// Getter
ilgenPrimGetter . Emit ( OpCodes . Ldarg_1 ) ;
ilgenPrimGetter . Emit ( OpCodes . Ldc_I4 , field . getOffset ( ) ) ;
2009-05-29 12:57:33 +04:00
ilgenPrimGetter . Emit ( OpCodes . Ldloc , primGetterThis ) ;
2007-09-24 15:57:00 +04:00
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 ) ;
2009-05-29 12:57:33 +04:00
ilgenPrimSetter . Emit ( OpCodes . Castclass , tw . TypeAsBaseType ) ;
2007-09-24 15:57:00 +04:00
ilgenPrimSetter . Emit ( OpCodes . Ldarg_1 ) ;
ilgenPrimSetter . Emit ( OpCodes . Ldc_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 . Emit ( OpCodes . Ldc_I4 , field . getOffset ( ) ) ;
2009-05-29 12:57:33 +04:00
ilgenObjGetter . Emit ( OpCodes . Ldloc , objGetterThis ) ;
2007-09-24 15:57:00 +04:00
fw . EmitGet ( ilgenObjGetter ) ;
2008-02-09 20:34:50 +03:00
fw . FieldTypeWrapper . EmitConvSignatureTypeToStackType ( ilgenObjGetter ) ;
2007-09-24 15:57:00 +04:00
ilgenObjGetter . Emit ( OpCodes . Stelem_Ref ) ;
// Setter
ilgenObjSetter . Emit ( OpCodes . Ldarg_0 ) ;
ilgenObjSetter . Emit ( OpCodes . Ldarg_1 ) ;
ilgenObjSetter . Emit ( OpCodes . Ldc_I4 , field . getOffset ( ) ) ;
ilgenObjSetter . Emit ( OpCodes . Ldelem_Ref ) ;
fw . FieldTypeWrapper . EmitCheckcast ( null , ilgenObjSetter ) ;
2008-02-09 20:34:50 +03:00
fw . FieldTypeWrapper . EmitConvStackTypeToSignatureType ( ilgenObjSetter , null ) ;
2007-09-24 15:57:00 +04:00
fw . EmitSet ( ilgenObjSetter ) ;
}
}
ilgenObjGetter . Emit ( OpCodes . Ret ) ;
ilgenPrimGetter . Emit ( OpCodes . Ret ) ;
ilgenObjSetter . Emit ( OpCodes . Ret ) ;
ilgenPrimSetter . Emit ( OpCodes . Ret ) ;
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 )
{
2008-09-01 09:19:04 +04:00
jlrField f = field . getField ( ) ;
2007-09-24 15:57:00 +04:00
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
2008-08-21 10:53:48 +04:00
return new FastFieldReflector ( ( jiObjectStreamField [ ] ) fieldsObj ) ;
2007-09-24 15:57:00 +04:00
#endif
}
2007-06-19 10:09:13 +04:00
}
2007-12-18 14:05:30 +03:00
static class Win32FileSystem
2007-06-19 08:50:45 +04:00
{
2007-06-27 10:14:54 +04:00
internal const int ACCESS_READ = 0x04 ;
2007-06-19 08:50:45 +04:00
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 "\\" ;
}
2007-08-21 11:16:36 +04:00
private static string CanonicalizePath ( string path )
{
try
{
2007-08-23 13:30:40 +04:00
System . IO . FileInfo fi = new System . IO . FileInfo ( path ) ;
if ( fi . DirectoryName = = null )
{
return path . Length > 1 & & path [ 1 ] = = ':' ? path . ToUpper ( ) : path ;
}
string dir = CanonicalizePath ( fi . DirectoryName ) ;
string name = fi . Name ;
try
{
2007-11-26 18:19:08 +03:00
if ( ! VirtualFileSystem . IsVirtualFS ( path ) )
2007-08-23 13:30:40 +04:00
{
2007-11-26 18:19:08 +03:00
string [ ] arr = System . IO . Directory . GetFileSystemEntries ( dir , name ) ;
if ( arr . Length = = 1 )
{
name = arr [ 0 ] ;
}
2007-08-23 13:30:40 +04:00
}
}
catch ( System . UnauthorizedAccessException )
{
}
catch ( System . IO . IOException )
2007-08-21 11:16:36 +04:00
{
}
2007-08-23 13:30:40 +04:00
return System . IO . Path . Combine ( dir , name ) ;
}
catch ( System . UnauthorizedAccessException )
{
2007-08-21 11:16:36 +04:00
}
2007-08-23 13:30:40 +04:00
catch ( System . IO . IOException )
2007-08-21 11:16:36 +04:00
{
}
2007-12-28 17:55:33 +03:00
catch ( System . Security . SecurityException )
{
}
2008-04-14 09:09:38 +04:00
catch ( System . NotSupportedException )
{
}
2007-08-23 13:30:40 +04:00
return path ;
2007-08-21 11:16:36 +04:00
}
2007-06-19 08:50:45 +04:00
public static string canonicalize0 ( object _this , string path )
{
2007-08-23 13:30:40 +04:00
#if FIRST_PASS
return null ;
#else
2007-08-21 11:16:36 +04:00
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:\"
2008-04-14 09:09:38 +04:00
int colon = path . IndexOf ( ':' , 2 ) ;
if ( colon ! = - 1 )
{
return CanonicalizePath ( path . Substring ( 0 , colon ) + System . IO . Path . DirectorySeparatorChar ) + path . Substring ( colon ) ;
}
2007-08-21 11:16:36 +04:00
return CanonicalizePath ( path + System . IO . Path . DirectorySeparatorChar ) ;
}
catch ( System . ArgumentException x )
{
throw new jiIOException ( x . Message ) ;
}
#endif
2007-06-19 08:50:45 +04:00
}
public static string canonicalizeWithPrefix0 ( object _this , string canonicalPrefix , string pathWithCanonicalPrefix )
{
2007-08-21 11:16:36 +04:00
return canonicalize0 ( _this , pathWithCanonicalPrefix ) ;
2007-06-19 08:50:45 +04:00
}
private static string GetPathFromFile ( object file )
{
#if FIRST_PASS
return null ;
#else
return ( ( jiFile ) file ) . getPath ( ) ;
#endif
}
public static int getBooleanAttributes ( object _this , object f )
{
try
{
2007-06-29 12:59:50 +04:00
string path = GetPathFromFile ( f ) ;
if ( VirtualFileSystem . IsVirtualFS ( path ) )
{
return VirtualFileSystem . GetBooleanAttributes ( path ) ;
}
System . IO . FileAttributes attr = System . IO . File . GetAttributes ( path ) ;
2007-06-19 08:50:45 +04:00
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 , object f , int access )
{
string path = GetPathFromFile ( f ) ;
2007-06-27 10:14:54 +04:00
if ( VirtualFileSystem . IsVirtualFS ( path ) )
{
return VirtualFileSystem . CheckAccess ( path , access ) ;
}
2007-06-19 08:50:45 +04:00
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
{
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 , object f )
{
try
{
return DateTimeToJavaLongTime ( System . IO . File . GetLastWriteTime ( GetPathFromFile ( f ) ) ) ;
}
catch ( System . UnauthorizedAccessException )
{
}
catch ( System . ArgumentException )
{
}
catch ( System . IO . IOException )
{
}
catch ( System . NotSupportedException )
{
}
return 0 ;
}
public static long getLength ( object _this , object f )
{
try
{
2007-06-27 10:14:54 +04:00
string path = GetPathFromFile ( f ) ;
if ( VirtualFileSystem . IsVirtualFS ( path ) )
{
return VirtualFileSystem . GetLength ( path ) ;
}
return new System . IO . FileInfo ( path ) . Length ;
2007-06-19 08:50:45 +04:00
}
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 , object 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 )
{
throw new jiIOException ( x . Message ) ;
}
catch ( System . NotSupportedException x )
{
throw new jiIOException ( x . Message ) ;
}
#endif
return false ;
}
public static bool delete0 ( object _this , object f )
{
2007-08-23 13:30:40 +04:00
System . IO . FileSystemInfo fileInfo = null ;
2007-06-19 08:50:45 +04:00
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 , object f )
{
try
{
2009-05-12 09:54:07 +04:00
string path = GetPathFromFile ( f ) ;
if ( VirtualFileSystem . IsVirtualFS ( path ) )
{
return VirtualFileSystem . List ( path ) ;
}
string [ ] l = System . IO . Directory . GetFileSystemEntries ( path ) ;
2007-06-19 08:50:45 +04:00
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 )
{
}
2009-05-11 12:31:59 +04:00
catch ( System . NotSupportedException )
{
}
2007-06-19 08:50:45 +04:00
return null ;
}
public static bool createDirectory ( object _this , object 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 , object f1 , object 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 , object 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 , object 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 System . IO . Directory . GetLogicalDrives ( ) )
{
2007-06-21 08:42:14 +04:00
char c = Char . ToUpper ( drive [ 0 ] ) ;
2007-06-19 08:50:45 +04:00
drives | = 1 < < ( c - 'A' ) ;
}
return drives ;
}
catch ( System . IO . IOException )
{
}
catch ( System . UnauthorizedAccessException )
{
}
return 0 ;
}
public static long getSpace0 ( object _this , object 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 ( )
{
}
}
2007-12-18 14:05:30 +03:00
static class UnixFileSystem
2007-06-19 08:50:45 +04:00
{
public static int getBooleanAttributes0 ( object _this , object f )
{
return Win32FileSystem . getBooleanAttributes ( _this , f ) ;
}
public static long getSpace ( object _this , object 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 , object f , int access )
{
return Win32FileSystem . checkAccess ( _this , f , access ) ;
}
public static long getLastModifiedTime ( object _this , object f )
{
return Win32FileSystem . getLastModifiedTime ( _this , f ) ;
}
public static long getLength ( object _this , object f )
{
return Win32FileSystem . getLength ( _this , f ) ;
}
public static bool setPermission ( object _this , object 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 , object f )
{
return Win32FileSystem . delete0 ( _this , f ) ;
}
public static string [ ] list ( object _this , object f )
{
return Win32FileSystem . list ( _this , f ) ;
}
public static bool createDirectory ( object _this , object f )
{
return Win32FileSystem . createDirectory ( _this , f ) ;
}
public static bool rename0 ( object _this , object f1 , object f2 )
{
return Win32FileSystem . rename0 ( _this , f1 , f2 ) ;
}
public static bool setLastModifiedTime ( object _this , object f , long time )
{
return Win32FileSystem . setLastModifiedTime ( _this , f , time ) ;
}
public static bool setReadOnly ( object _this , object f )
{
return Win32FileSystem . setReadOnly ( _this , f ) ;
}
public static void initIDs ( )
{
}
}
2007-06-15 17:53:42 +04:00
}
2007-05-28 14:15:23 +04:00
namespace lang
{
2007-05-31 11:13:46 +04:00
namespace reflect
{
2007-12-18 14:05:30 +03:00
static class Array
2007-05-31 11:13:46 +04:00
{
#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 ( object componentType , int length )
{
return null ;
}
public static object multiNewArray ( object componentType , int [ ] dimensions )
{
return null ;
}
#else
2007-06-09 12:33:09 +04:00
private static SystemArray CheckArray ( object arrayObj )
2007-05-31 11:13:46 +04:00
{
if ( arrayObj = = null )
{
throw new jlNullPointerException ( ) ;
}
2007-06-09 12:33:09 +04:00
SystemArray arr = arrayObj as SystemArray ;
2007-05-31 11:13:46 +04:00
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 )
{
2007-06-09 12:33:09 +04:00
SystemArray arr = CheckArray ( arrayObj ) ;
2007-05-31 11:13:46 +04:00
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 )
{
2007-08-08 16:52:33 +04:00
if ( arrayObj = = null )
2007-05-31 11:13:46 +04:00
{
2007-08-08 16:52:33 +04:00
throw new jlNullPointerException ( ) ;
2007-05-31 11:13:46 +04:00
}
2007-08-08 16:52:33 +04:00
Type type = arrayObj . GetType ( ) ;
if ( type . IsArray & & ClassLoaderWrapper . GetWrapperFromType ( type . GetElementType ( ) ) . IsPrimitive )
2007-05-31 11:13:46 +04:00
{
2007-08-08 16:52:33 +04:00
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 ;
}
2007-05-31 11:13:46 +04:00
}
try
{
CheckArray ( arrayObj ) . SetValue ( value , index ) ;
}
2007-06-09 12:33:09 +04:00
catch ( InvalidCastException )
2007-05-31 11:13:46 +04:00
{
throw new jlIllegalArgumentException ( "argument type mismatch" ) ;
}
2007-06-09 12:33:09 +04:00
catch ( IndexOutOfRangeException )
2007-05-31 11:13:46 +04:00
{
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 ( object componentType , int length )
{
if ( componentType = = null )
{
throw new jlNullPointerException ( ) ;
}
2007-06-01 15:50:46 +04:00
if ( componentType = = jlVoid . TYPE )
{
throw new jlIllegalArgumentException ( ) ;
}
2007-05-31 11:13:46 +04:00
if ( length < 0 )
{
throw new jlNegativeArraySizeException ( ) ;
}
try
{
TypeWrapper wrapper = TypeWrapper . FromClass ( componentType ) ;
wrapper . Finish ( ) ;
2008-08-06 09:25:18 +04:00
object obj = SystemArray . CreateInstance ( wrapper . TypeAsArrayType , length ) ;
if ( wrapper . IsGhost | | wrapper . IsGhostArray )
{
IKVM . Runtime . GhostTag . SetTag ( obj , wrapper . MakeArrayType ( 1 ) ) ;
}
return obj ;
2007-05-31 11:13:46 +04:00
}
catch ( RetargetableJavaException x )
{
throw x . ToJava ( ) ;
}
}
public static object multiNewArray ( object componentType , int [ ] dimensions )
{
if ( componentType = = null | | dimensions = = null )
{
throw new jlNullPointerException ( ) ;
}
2007-06-01 15:50:46 +04:00
if ( componentType = = jlVoid . TYPE )
{
throw new jlIllegalArgumentException ( ) ;
}
2007-05-31 11:13:46 +04:00
if ( dimensions . Length = = 0 | | dimensions . Length > 255 )
{
throw new jlIllegalArgumentException ( ) ;
}
try
{
2007-08-08 16:52:33 +04:00
TypeWrapper wrapper = TypeWrapper . FromClass ( componentType ) . MakeArrayType ( dimensions . Length ) ;
2007-05-31 11:13:46 +04:00
wrapper . Finish ( ) ;
2008-08-06 09:25:18 +04:00
object obj = IKVM . Runtime . ByteCodeHelper . multianewarray ( wrapper . TypeAsArrayType . TypeHandle , dimensions ) ;
if ( wrapper . IsGhostArray )
{
IKVM . Runtime . GhostTag . SetTag ( obj , wrapper ) ;
}
return obj ;
2007-05-31 11:13:46 +04:00
}
catch ( RetargetableJavaException x )
{
throw x . ToJava ( ) ;
}
}
#endif // FIRST_PASS
}
}
2007-12-18 14:05:30 +03:00
static class Class
2007-05-28 14:15:23 +04:00
{
public static object forName0 ( string name , bool initialize , object loader )
{
#if FIRST_PASS
return null ;
#else
2007-07-02 11:11:48 +04:00
//Console.WriteLine("forName: " + name + ", loader = " + loader);
2007-05-28 14:15:23 +04:00
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 )
{
2008-02-29 11:03:09 +03:00
tw = ClassLoaderWrapper . GetWrapperFromType ( type ) ;
2007-05-28 14:15:23 +04:00
}
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 )
{
tw . Finish ( ) ;
tw . RunClassInit ( ) ;
}
return tw . ClassObject ;
#endif
}
public static bool isInstance ( object thisClass , object obj )
{
2007-05-31 11:13:46 +04:00
return TypeWrapper . FromClass ( thisClass ) . IsInstance ( obj ) ;
2007-05-28 14:15:23 +04:00
}
public static bool isAssignableFrom ( object thisClass , object otherClass )
{
2007-06-01 15:50:46 +04:00
#if ! FIRST_PASS
if ( otherClass = = null )
{
throw new jlNullPointerException ( ) ;
}
#endif
2007-05-28 14:15:23 +04:00
return TypeWrapper . FromClass ( otherClass ) . IsAssignableTo ( TypeWrapper . FromClass ( thisClass ) ) ;
}
public static bool isInterface ( object thisClass )
{
return TypeWrapper . FromClass ( thisClass ) . IsInterface ;
}
public static bool isArray ( object thisClass )
{
return TypeWrapper . FromClass ( thisClass ) . IsArray ;
}
public static bool isPrimitive ( object thisClass )
{
return TypeWrapper . FromClass ( thisClass ) . IsPrimitive ;
}
public static string getName0 ( object 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 ;
}
2009-07-29 11:04:42 +04:00
public static string getSigName ( object thisClass )
{
return TypeWrapper . FromClass ( thisClass ) . SigName ;
}
2007-05-28 14:15:23 +04:00
public static object getClassLoader0 ( object thisClass )
{
return TypeWrapper . FromClass ( thisClass ) . GetClassLoader ( ) . GetJavaClassLoader ( ) ;
}
public static object getSuperclass ( object thisClass )
{
TypeWrapper super = TypeWrapper . FromClass ( thisClass ) . BaseTypeWrapper ;
return super ! = null ? super . ClassObject : null ;
}
public static object getInterfaces ( object 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 ] = ( jlClass ) ifaces [ i ] . ClassObject ;
}
return interfaces ;
#endif
}
public static object getComponentType ( object thisClass )
{
TypeWrapper tw = TypeWrapper . FromClass ( thisClass ) ;
return tw . IsArray ? tw . ElementTypeWrapper . ClassObject : null ;
}
public static int getModifiers ( object thisClass )
{
2007-10-22 14:25:54 +04:00
// 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 ;
2007-05-28 14:15:23 +04:00
}
public static object [ ] getSigners ( object thisClass )
{
2007-12-27 18:16:49 +03:00
#if FIRST_PASS
return null ;
#else
return ( ( jlClass ) thisClass ) . signers ;
#endif
2007-05-28 14:15:23 +04:00
}
public static void setSigners ( object thisClass , object [ ] signers )
{
2007-12-27 18:16:49 +03:00
#if ! FIRST_PASS
( ( jlClass ) thisClass ) . signers = signers ;
#endif
2007-05-28 14:15:23 +04:00
}
public static object [ ] getEnclosingMethod0 ( object thisClass )
{
TypeWrapper tw = TypeWrapper . FromClass ( thisClass ) ;
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 ( object thisClass )
{
try
{
TypeWrapper wrapper = TypeWrapper . FromClass ( thisClass ) ;
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 ( ) ;
2007-06-09 12:33:09 +04:00
if ( SystemArray . IndexOf ( decl . InnerClasses , wrapper ) = = - 1 )
2007-05-28 14:15:23 +04:00
{
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 object getProtectionDomain0 ( object thisClass )
{
2007-12-27 18:16:49 +03:00
#if FIRST_PASS
return null ;
#else
2007-05-28 14:15:23 +04:00
TypeWrapper wrapper = TypeWrapper . FromClass ( thisClass ) ;
while ( wrapper . IsArray )
{
wrapper = wrapper . ElementTypeWrapper ;
}
2007-12-27 18:16:49 +03:00
object pd = ( ( jlClass ) wrapper . ClassObject ) . pd ;
2007-10-21 11:14:53 +04:00
if ( pd = = null )
2007-06-09 12:33:09 +04:00
{
2007-10-21 11:14:53 +04:00
// 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 )
2007-06-09 12:33:09 +04:00
{
2007-10-21 11:14:53 +04:00
pd = acl . GetProtectionDomain ( ) ;
2007-06-09 12:33:09 +04:00
}
}
return pd ;
2007-12-27 18:16:49 +03:00
#endif
2007-05-28 14:15:23 +04:00
}
public static void setProtectionDomain0 ( object thisClass , object pd )
{
2007-12-27 18:16:49 +03:00
#if ! FIRST_PASS
( ( jlClass ) thisClass ) . pd = ( ProtectionDomain ) pd ;
#endif
2007-05-28 14:15:23 +04:00
}
public static object getPrimitiveClass ( string name )
{
2009-07-16 10:29:32 +04:00
// 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
2007-05-28 14:15:23 +04:00
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 ( object thisClass )
{
string sig = TypeWrapper . FromClass ( thisClass ) . GetGenericSignature ( ) ;
if ( sig = = null )
{
return null ;
}
return sig . Replace ( '.' , '/' ) ;
}
2008-02-29 11:03:09 +03:00
internal static object AnnotationsToMap ( object [ ] objAnn )
2007-05-28 14:15:23 +04:00
{
#if FIRST_PASS
return null ;
#else
2008-02-19 19:52:53 +03:00
global :: java . util . HashMap map = new global :: java . util . HashMap ( ) ;
if ( objAnn ! = null )
2007-05-28 14:15:23 +04:00
{
2008-02-19 19:52:53 +03:00
foreach ( object obj in objAnn )
2007-05-28 14:15:23 +04:00
{
2008-02-19 19:52:53 +03:00
Annotation a = obj as Annotation ;
if ( a ! = null )
{
2008-02-29 11:03:09 +03:00
global :: ikvm . @internal . AnnotationAttributeBase . freeze ( a ) ;
2008-02-19 19:52:53 +03:00
map . put ( a . annotationType ( ) , a ) ;
}
2007-05-28 14:15:23 +04:00
}
}
2008-02-19 19:52:53 +03:00
return map ;
2007-05-28 14:15:23 +04:00
#endif
}
2008-02-29 11:03:09 +03:00
public static object getDeclaredAnnotationsImpl ( object thisClass )
{
#if FIRST_PASS
return null ;
#else
TypeWrapper wrapper = TypeWrapper . FromClass ( thisClass ) ;
wrapper . Finish ( ) ;
return AnnotationsToMap ( wrapper . GetDeclaredAnnotations ( ) ) ;
#endif
}
2007-05-28 14:15:23 +04:00
public static object getDeclaredFields0 ( object 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 ( ) ;
2007-11-26 14:01:29 +03:00
List < jlrField > list = new List < jlrField > ( ) ;
2007-05-28 14:15:23 +04:00
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
{
fields [ i ] . FieldTypeWrapper . EnsureLoadable ( wrapper . GetClassLoader ( ) ) ;
2007-11-26 14:01:29 +03:00
list . Add ( ( jlrField ) fields [ i ] . ToField ( false ) ) ;
2007-05-28 14:15:23 +04:00
}
}
2007-11-26 14:01:29 +03:00
return list . ToArray ( ) ;
2007-05-28 14:15:23 +04:00
}
catch ( RetargetableJavaException x )
{
throw x . ToJava ( ) ;
}
finally
{
Profiler . Leave ( "Class.getDeclaredFields0" ) ;
}
#endif
}
public static object getDeclaredMethods0 ( object 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 ) ;
}
// we need to look through the array for unloadable types, because we may not let them
// escape into the 'wild'
MethodWrapper [ ] methods = wrapper . GetMethods ( ) ;
2007-11-26 14:01:29 +03:00
List < jlrMethod > list = new List < jlrMethod > ( ) ;
2007-05-28 14:15:23 +04:00
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 ) )
{
2007-05-29 20:27:08 +04:00
methods [ i ] . ReturnType . EnsureLoadable ( wrapper . GetClassLoader ( ) ) ;
TypeWrapper [ ] args = methods [ i ] . GetParameters ( ) ;
for ( int j = 0 ; j < args . Length ; j + + )
2007-05-28 14:15:23 +04:00
{
2007-05-29 20:27:08 +04:00
args [ j ] . EnsureLoadable ( wrapper . GetClassLoader ( ) ) ;
2007-05-28 14:15:23 +04:00
}
2007-11-26 14:01:29 +03:00
list . Add ( ( jlrMethod ) methods [ i ] . ToMethodOrConstructor ( false ) ) ;
2007-05-28 14:15:23 +04:00
}
}
2007-11-26 14:01:29 +03:00
return list . ToArray ( ) ;
2007-05-28 14:15:23 +04:00
}
catch ( RetargetableJavaException x )
{
throw x . ToJava ( ) ;
}
finally
{
Profiler . Leave ( "Class.getDeclaredMethods0" ) ;
}
#endif
}
public static object getDeclaredConstructors0 ( object 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 ) ;
}
// we need to look through the array for unloadable types, because we may not let them
// escape into the 'wild'
MethodWrapper [ ] methods = wrapper . GetMethods ( ) ;
2007-11-26 14:01:29 +03:00
List < jlrConstructor > list = new List < jlrConstructor > ( ) ;
2007-05-28 14:15:23 +04:00
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)
2007-06-01 15:50:46 +04:00
if ( ! methods [ i ] . IsHideFromReflection
& & methods [ i ] . Name = = "<init>"
& & ( ! publicOnly | | methods [ i ] . IsPublic ) )
2007-05-28 14:15:23 +04:00
{
2007-06-01 15:50:46 +04:00
TypeWrapper [ ] args = methods [ i ] . GetParameters ( ) ;
for ( int j = 0 ; j < args . Length ; j + + )
2007-05-28 14:15:23 +04:00
{
2007-06-01 15:50:46 +04:00
args [ j ] . EnsureLoadable ( wrapper . GetClassLoader ( ) ) ;
2007-05-28 14:15:23 +04:00
}
2007-11-26 14:01:29 +03:00
list . Add ( ( jlrConstructor ) methods [ i ] . ToMethodOrConstructor ( false ) ) ;
2007-05-28 14:15:23 +04:00
}
}
2007-11-26 14:01:29 +03:00
return list . ToArray ( ) ;
2007-05-28 14:15:23 +04:00
}
catch ( RetargetableJavaException x )
{
throw x . ToJava ( ) ;
}
finally
{
Profiler . Leave ( "Class.getDeclaredConstructors0" ) ;
}
#endif
}
public static object getDeclaredClasses0 ( object 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 + + )
{
wrappers [ i ] . Finish ( ) ;
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 ) ) ;
}
innerclasses [ i ] = ( jlClass ) wrappers [ i ] . ClassObject ;
}
return innerclasses ;
}
catch ( RetargetableJavaException x )
{
throw x . ToJava ( ) ;
}
#endif
}
public static bool desiredAssertionStatus0 ( object clazz )
{
2007-09-12 10:51:37 +04:00
return IKVM . Runtime . Assertions . IsEnabled ( TypeWrapper . FromClass ( clazz ) ) ;
2007-05-28 14:15:23 +04:00
}
}
2007-12-18 14:05:30 +03:00
static class ClassLoader
2007-05-28 14:15:23 +04:00
{
#if ! FIRST_PASS
private static jlClassNotFoundException classNotFoundException ;
#endif
public static object defineClass0 ( object thisClassLoader , string name , byte [ ] b , int off , int len , object pd )
{
return defineClass1 ( thisClassLoader , name , b , off , len , pd , null ) ;
}
public static object defineClass1 ( object 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 ;
}
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 ( object thisClassLoader , string name , object b , int off , int len , object pd , string source )
{
#if FIRST_PASS
return null ;
#else
jnByteBuffer bb = ( jnByteBuffer ) b ;
byte [ ] buf = new byte [ bb . remaining ( ) ] ;
bb . get ( buf ) ;
return defineClass1 ( thisClassLoader , name , buf , 0 , buf . Length , pd , source ) ;
#endif
}
public static void resolveClass0 ( object thisClassLoader , object clazz )
{
// no-op
}
public static object findBootstrapClass ( object thisClassLoader , string name )
{
#if FIRST_PASS
return null ;
#else
TypeWrapper tw ;
try
{
tw = ClassLoaderWrapper . GetBootstrapClassLoader ( ) . LoadClassByDottedNameFast ( name ) ;
}
catch ( RetargetableJavaException x )
{
throw x . ToJava ( ) ;
}
if ( tw = = null )
{
// HACK for efficiency, we don't allocate a new exception here
// (as this exception is thrown for *every* non-boot class that we load and
// the exception is thrown away by our caller anyway)
if ( classNotFoundException = = null )
{
jlClassNotFoundException ex = new jlClassNotFoundException ( null , null ) ;
ex . setStackTrace ( new jlStackTraceElement [ ] { new jlStackTraceElement ( "java.lang.ClassLoader" , "findBootstrapClass" , null , - 2 ) } ) ;
classNotFoundException = ex ;
}
throw classNotFoundException ;
}
return tw . ClassObject ;
#endif
}
public static object findLoadedClass0 ( object thisClassLoader , string name )
{
ClassLoaderWrapper loader = ClassLoaderWrapper . GetClassLoaderWrapper ( thisClassLoader ) ;
TypeWrapper tw = loader . GetLoadedClass ( name ) ;
return tw ! = null ? tw . ClassObject : null ;
}
2007-12-18 14:05:30 +03:00
internal static class NativeLibrary
2007-05-28 14:15:23 +04:00
{
public static void load ( object thisNativeLibrary , string name )
{
2007-12-18 12:56:11 +03:00
#if ! FIRST_PASS
2009-05-12 08:30:10 +04:00
if ( VirtualFileSystem . IsVirtualFS ( name ) )
2007-06-09 12:33:09 +04:00
{
2007-07-05 15:53:06 +04:00
// we fake success for native libraries loaded from VFS
2009-03-09 12:01:36 +03:00
( ( global :: java . lang . ClassLoader . NativeLibrary ) thisNativeLibrary ) . handle = - 1 ;
2007-06-09 12:33:09 +04:00
}
2007-07-05 15:53:06 +04:00
else
{
2007-12-28 17:55:33 +03:00
doLoad ( thisNativeLibrary , name ) ;
2007-07-05 15:53:06 +04:00
}
2007-12-18 12:56:11 +03:00
#endif
2007-06-09 12:33:09 +04:00
}
2007-12-28 17:55:33 +03:00
#if ! FIRST_PASS
2008-12-22 10:34:37 +03:00
// 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)]
2007-12-28 17:55:33 +03:00
private static void doLoad ( object thisNativeLibrary , string name )
{
2009-03-09 12:01:36 +03:00
global :: java . lang . ClassLoader . NativeLibrary lib = ( global :: java . lang . ClassLoader . NativeLibrary ) thisNativeLibrary ;
lib . handle = IKVM . Runtime . JniHelper . LoadLibrary ( name , TypeWrapper . FromClass ( lib . fromClass ) . GetClassLoader ( ) ) ;
2007-12-28 17:55:33 +03:00
}
#endif
2007-05-28 14:15:23 +04:00
public static long find ( object thisNativeLibrary , string name )
{
// TODO
throw new NotImplementedException ( ) ;
}
public static void unload ( object thisNativeLibrary )
{
2009-03-09 12:01:36 +03:00
#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
2007-05-28 14:15:23 +04:00
}
}
public static object retrieveDirectives ( )
{
2007-09-12 10:51:37 +04:00
return IKVM . Runtime . Assertions . RetrieveDirectives ( ) ;
2007-05-28 14:15:23 +04:00
}
}
2007-12-18 14:05:30 +03:00
static class Compiler
2007-06-11 13:17:29 +04:00
{
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 ( )
{
}
}
2007-12-18 14:05:30 +03:00
static class Double
2007-06-11 13:17:29 +04:00
{
public static long doubleToRawLongBits ( double value )
{
2008-05-09 09:59:59 +04:00
IKVM . Runtime . DoubleConverter converter = new IKVM . Runtime . DoubleConverter ( ) ;
return IKVM . Runtime . DoubleConverter . ToLong ( value , ref converter ) ;
2007-06-11 13:17:29 +04:00
}
public static double longBitsToDouble ( long bits )
{
2008-05-09 09:59:59 +04:00
IKVM . Runtime . DoubleConverter converter = new IKVM . Runtime . DoubleConverter ( ) ;
return IKVM . Runtime . DoubleConverter . ToDouble ( bits , ref converter ) ;
2007-06-11 13:17:29 +04:00
}
}
2007-12-18 14:05:30 +03:00
static class Float
2007-06-11 13:17:29 +04:00
{
public static int floatToRawIntBits ( float value )
{
2008-05-09 09:59:59 +04:00
IKVM . Runtime . FloatConverter converter = new IKVM . Runtime . FloatConverter ( ) ;
return IKVM . Runtime . FloatConverter . ToInt ( value , ref converter ) ;
2007-06-11 13:17:29 +04:00
}
public static float intBitsToFloat ( int bits )
{
2008-05-09 09:59:59 +04:00
IKVM . Runtime . FloatConverter converter = new IKVM . Runtime . FloatConverter ( ) ;
return IKVM . Runtime . FloatConverter . ToFloat ( bits , ref converter ) ;
2007-06-11 13:17:29 +04:00
}
}
2007-12-18 14:05:30 +03:00
static class Package
2007-05-28 14:15:23 +04:00
{
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 ( ) ;
}
}
2007-12-18 14:05:30 +03:00
static class ProcessEnvironment
2007-06-09 12:33:09 +04:00
{
public static string environmentBlock ( )
{
StringBuilder sb = new StringBuilder ( ) ;
2008-08-15 16:01:06 +04:00
foreach ( global :: System . Collections . DictionaryEntry de in Environment . GetEnvironmentVariables ( ) )
2007-06-09 12:33:09 +04:00
{
sb . Append ( de . Key ) . Append ( '=' ) . Append ( de . Value ) . Append ( ' \ u0000 ' ) ;
}
if ( sb . Length = = 0 )
{
sb . Append ( ' \ u0000 ' ) ;
}
sb . Append ( ' \ u0000 ' ) ;
return sb . ToString ( ) ;
}
}
2007-12-18 14:05:30 +03:00
static class Runtime
2007-06-09 12:33:09 +04:00
{
public static int availableProcessors ( object thisRuntime )
{
2008-04-23 09:22:31 +04:00
return Environment . ProcessorCount ;
2007-06-09 12:33:09 +04:00
}
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 ( ) ;
}
}
2007-12-18 14:05:30 +03:00
static class SecurityManager
2007-06-11 13:17:29 +04:00
{
2007-12-27 18:16:49 +03:00
// 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 ;
2007-06-11 13:17:29 +04:00
public static object getClassContext ( object thisSecurityManager )
{
#if FIRST_PASS
return null ;
#else
2007-11-26 14:01:29 +03:00
List < jlClass > stack = new List < jlClass > ( ) ;
2007-06-11 13:17:29 +04:00
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
2007-08-07 11:44:42 +04:00
if ( IKVM . NativeCode . sun . reflect . Reflection . IsHideFromJava ( method )
2007-06-11 13:17:29 +04:00
| | type = = null
| | type . Assembly = = typeof ( object ) . Assembly
| | type . Assembly = = typeof ( SecurityManager ) . Assembly
2007-12-27 18:16:49 +03:00
| | type . Assembly = = jniAssembly
2007-06-11 13:17:29 +04:00
| | type = = typeof ( jlrConstructor )
| | type = = typeof ( jlrMethod ) )
{
continue ;
}
if ( type = = typeof ( jlSecurityManager ) )
{
continue ;
}
2007-11-26 14:01:29 +03:00
stack . Add ( ( jlClass ) ClassLoaderWrapper . GetWrapperFromType ( type ) . ClassObject ) ;
2007-06-11 13:17:29 +04:00
}
2007-11-26 14:01:29 +03:00
return stack . ToArray ( ) ;
2007-06-11 13:17:29 +04:00
#endif
}
public static object currentClassLoader0 ( object thisSecurityManager )
{
object 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 object currentLoadedClass0 ( object thisSecurityManager )
{
throw new NotImplementedException ( ) ;
}
}
2007-12-18 14:05:30 +03:00
static class StrictMath
2007-06-11 13:17:29 +04:00
{
public static double sin ( double d )
{
2009-02-16 08:13:49 +03:00
#if FIRST_PASS
return 0 ;
#else
return global :: ikvm . @internal . JMath . sin ( d ) ;
#endif
2007-06-11 13:17:29 +04:00
}
public static double cos ( double d )
{
2009-02-16 08:13:49 +03:00
#if FIRST_PASS
return 0 ;
#else
return global :: ikvm . @internal . JMath . cos ( d ) ;
#endif
2007-06-11 13:17:29 +04:00
}
public static double tan ( double d )
{
2009-02-16 08:13:49 +03:00
#if FIRST_PASS
return 0 ;
#else
return global :: ikvm . @internal . JMath . tan ( d ) ;
#endif
2007-06-11 13:17:29 +04:00
}
public static double asin ( double d )
{
2009-02-16 08:13:49 +03:00
#if FIRST_PASS
return 0 ;
#else
return global :: ikvm . @internal . JMath . asin ( d ) ;
#endif
2007-06-11 13:17:29 +04:00
}
public static double acos ( double d )
{
2009-02-16 08:13:49 +03:00
#if FIRST_PASS
return 0 ;
#else
return global :: ikvm . @internal . JMath . acos ( d ) ;
#endif
2007-06-11 13:17:29 +04:00
}
public static double atan ( double d )
{
2009-02-16 08:13:49 +03:00
#if FIRST_PASS
return 0 ;
#else
return global :: ikvm . @internal . JMath . atan ( d ) ;
#endif
2007-06-11 13:17:29 +04:00
}
public static double exp ( double d )
{
2009-02-16 08:13:49 +03:00
#if FIRST_PASS
return 0 ;
#else
return global :: ikvm . @internal . JMath . exp ( d ) ;
#endif
2007-06-11 13:17:29 +04:00
}
public static double log ( double d )
{
2009-02-16 08:13:49 +03:00
// FPU behavior is correct
2007-06-11 13:17:29 +04:00
return Math . Log ( d ) ;
}
public static double log10 ( double d )
{
2009-02-16 08:13:49 +03:00
// FPU behavior is correct
2007-06-11 13:17:29 +04:00
return Math . Log10 ( d ) ;
}
public static double sqrt ( double d )
{
2009-02-16 08:13:49 +03:00
// FPU behavior is correct
2007-06-11 13:17:29 +04:00
return Math . Sqrt ( d ) ;
}
public static double cbrt ( double d )
{
return Math . Pow ( d , 1.0 / 3.0 ) ;
}
public static double IEEEremainder ( double f1 , double f2 )
{
2009-02-16 08:13:49 +03:00
#if FIRST_PASS
return 0 ;
#else
return global :: ikvm . @internal . JMath . IEEEremainder ( f1 , f2 ) ;
#endif
2007-06-11 13:17:29 +04:00
}
public static double ceil ( double d )
{
2009-02-16 08:13:49 +03:00
#if FIRST_PASS
return 0 ;
#else
return global :: ikvm . @internal . JMath . ceil ( d ) ;
#endif
2007-06-11 13:17:29 +04:00
}
public static double floor ( double d )
{
2009-02-16 08:13:49 +03:00
#if FIRST_PASS
return 0 ;
#else
return global :: ikvm . @internal . JMath . floor ( d ) ;
#endif
2007-06-11 13:17:29 +04:00
}
public static double atan2 ( double y , double x )
{
2009-02-16 08:13:49 +03:00
#if FIRST_PASS
return 0 ;
#else
return global :: ikvm . @internal . JMath . atan2 ( y , x ) ;
#endif
2007-06-11 13:17:29 +04:00
}
public static double pow ( double x , double y )
{
2009-02-16 08:13:49 +03:00
#if FIRST_PASS
return 0 ;
#else
return global :: ikvm . @internal . JMath . pow ( x , y ) ;
#endif
2007-06-11 13:17:29 +04:00
}
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 )
{
2009-02-16 08:13:49 +03:00
#if FIRST_PASS
return 0 ;
#else
return global :: ikvm . @internal . JMath . rint ( d ) ;
#endif
2007-06-11 13:17:29 +04:00
}
public static double hypot ( double a , double b )
{
return a * a + b * b ;
}
public static double expm1 ( double d )
{
return Math . Exp ( d ) - 1.0 ;
}
public static double log1p ( double d )
{
return Math . Log ( d + 1.0 ) ;
}
}
2007-12-18 14:05:30 +03:00
static class System
2007-06-09 12:33:09 +04:00
{
public static void arraycopy ( object src , int srcPos , object dest , int destPos , int length )
{
IKVM . Runtime . ByteCodeHelper . arraycopy ( src , srcPos , dest , destPos , length ) ;
}
}
2007-12-18 14:05:30 +03:00
static class Thread
2007-06-05 10:57:18 +04:00
{
private static readonly object mainThreadGroup ;
2007-06-05 13:57:09 +04:00
2007-06-05 10:57:18 +04:00
#if ! FIRST_PASS
static Thread ( )
{
2008-04-23 08:25:21 +04:00
mainThreadGroup = new jlThreadGroup ( jlThreadGroup . createRootGroup ( ) , "main" ) ;
2007-12-27 18:16:49 +03:00
}
2007-06-09 12:33:09 +04:00
#endif
2007-06-17 17:28:41 +04:00
2008-04-25 08:48:57 +04:00
public static object getMainThreadGroup ( )
2007-06-05 10:57:18 +04:00
{
2008-04-25 08:48:57 +04:00
return mainThreadGroup ;
2007-06-09 12:33:09 +04:00
}
2007-06-05 10:57:18 +04:00
// this is called from JniInterface.cs
internal static void WaitUntilLastJniThread ( )
{
2007-08-17 13:58:37 +04:00
#if ! FIRST_PASS
int count = jlThread . currentThread ( ) . isDaemon ( ) ? 0 : 1 ;
2008-04-25 08:48:57 +04:00
while ( Interlocked . CompareExchange ( ref jlThread . nonDaemonCount [ 0 ] , 0 , 0 ) > count )
2007-08-17 13:58:37 +04:00
{
SystemThreadingThread . Sleep ( 1 ) ;
}
#endif
2007-06-05 10:57:18 +04:00
}
// this is called from JniInterface.cs
internal static void AttachThreadFromJni ( object threadGroup )
{
#if ! FIRST_PASS
2008-04-25 08:48:57 +04:00
if ( threadGroup = = null )
2007-07-18 12:37:42 +04:00
{
2008-04-25 08:48:57 +04:00
threadGroup = mainThreadGroup ;
2007-07-18 12:37:42 +04:00
}
2008-04-25 08:48:57 +04:00
if ( jlThread . current = = null )
2007-06-05 10:57:18 +04:00
{
2008-04-25 08:48:57 +04:00
new jlThread ( ( jlThreadGroup ) threadGroup ) ;
2007-06-05 10:57:18 +04:00
}
#endif
}
}
2007-12-18 14:05:30 +03:00
static class VMThread
2007-06-05 10:57:18 +04:00
{
2008-04-25 08:48:57 +04:00
// this method is called from ikvm.runtime.Startup.exitMainThread() and from JNI
2007-06-05 10:57:18 +04:00
public static void jniDetach ( )
{
2008-04-25 08:48:57 +04:00
#if ! FIRST_PASS
jlThread . currentThread ( ) . die ( ) ;
#endif
2007-06-05 10:57:18 +04:00
}
}
2009-02-10 18:21:41 +03:00
static class ProcessImpl
{
public static string mapVfsExecutable ( string path )
{
2009-05-12 08:30:10 +04:00
if ( VirtualFileSystem . IsVirtualFS ( path ) )
2009-02-10 18:21:41 +03:00
{
2009-05-12 08:30:10 +04:00
return VirtualFileSystem . MapExecutable ( path ) ;
2009-02-10 18:21:41 +03:00
}
return path ;
}
}
2007-05-28 14:15:23 +04:00
namespace reflect
{
2007-12-18 14:05:30 +03:00
static class Proxy
2007-05-28 14:15:23 +04:00
{
public static object defineClass0 ( object classLoader , string name , byte [ ] b , int off , int len )
{
return ClassLoader . defineClass1 ( classLoader , name , b , off , len , null , null ) ;
}
}
2007-09-10 10:16:49 +04:00
2008-02-29 11:03:09 +03:00
static class Field
{
public static object getDeclaredAnnotationsImpl ( object thisField )
{
FieldWrapper fw = FieldWrapper . FromField ( thisField ) ;
return Class . AnnotationsToMap ( fw . DeclaringType . GetFieldAnnotations ( fw ) ) ;
}
}
2007-12-18 14:05:30 +03:00
static class Method
2007-09-10 10:16:49 +04:00
{
2008-02-29 11:03:09 +03:00
public static object getDeclaredAnnotationsImpl ( object methodOrConstructor )
2007-09-10 10:16:49 +04:00
{
2008-02-29 11:03:09 +03:00
MethodWrapper mw = MethodWrapper . FromMethodOrConstructor ( methodOrConstructor ) ;
return Class . AnnotationsToMap ( mw . DeclaringType . GetMethodAnnotations ( mw ) ) ;
2007-09-10 10:16:49 +04:00
}
2008-02-29 11:03:09 +03:00
public static object [ ] [ ] getParameterAnnotationsImpl ( object methodOrConstructor )
2007-09-10 10:16:49 +04:00
{
2008-02-29 11:03:09 +03:00
#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 )
{
global :: ikvm . @internal . AnnotationAttributeBase . freeze ( a ) ;
list . Add ( a ) ;
}
}
ann [ i ] = list . ToArray ( ) ;
}
return ann ;
#endif
2007-09-10 10:16:49 +04:00
}
2008-02-29 11:03:09 +03:00
public static object getDefaultValue ( object thisMethod )
2007-09-10 10:16:49 +04:00
{
2008-02-29 11:03:09 +03:00
MethodWrapper mw = MethodWrapper . FromMethodOrConstructor ( thisMethod ) ;
return mw . DeclaringType . GetAnnotationDefault ( mw ) ;
2007-09-10 10:16:49 +04:00
}
}
2007-05-28 14:15:23 +04:00
}
}
2007-06-19 20:30:09 +04:00
2007-07-12 12:40:32 +04:00
namespace net
{
2007-12-18 14:05:30 +03:00
static class DatagramPacket
2007-07-12 12:40:32 +04:00
{
public static void init ( )
{
}
}
2007-12-18 14:05:30 +03:00
static class InetAddress
2007-07-12 12:40:32 +04:00
{
public static void init ( )
{
}
}
2007-12-18 14:05:30 +03:00
static class InetAddressImplFactory
2007-07-12 12:40:32 +04:00
{
public static bool isIPv6Supported ( )
{
// TODO System.Net.Sockets.Socket.OSSupportsIPv6;
return false ;
}
}
2007-12-18 14:05:30 +03:00
static class Inet4Address
2007-07-12 12:40:32 +04:00
{
public static void init ( )
{
}
}
2007-12-18 14:05:30 +03:00
static class Inet4AddressImpl
2007-07-12 12:40:32 +04:00
{
public static string getLocalHostName ( object thisInet4AddressImpl )
{
2007-07-12 12:46:25 +04:00
#if FIRST_PASS
return null ;
#else
2007-07-12 12:40:32 +04:00
try
{
return System . Net . Dns . GetHostName ( ) ;
}
catch ( System . Net . Sockets . SocketException x )
{
throw new jnUnknownHostException ( x . Message ) ;
}
2007-07-12 12:46:25 +04:00
#endif
2007-07-12 12:40:32 +04:00
}
public static object lookupAllHostAddr ( object thisInet4AddressImpl , string hostname )
{
#if FIRST_PASS
return null ;
#else
try
{
System . Net . IPAddress [ ] addr = System . Net . Dns . GetHostAddresses ( hostname ) ;
2007-11-26 14:01:29 +03:00
List < jnInetAddress > addresses = new List < jnInetAddress > ( ) ;
2007-07-12 12:40:32 +04:00
for ( int i = 0 ; i < addr . Length ; i + + )
{
byte [ ] b = addr [ i ] . GetAddressBytes ( ) ;
if ( b . Length = = 4 )
{
2007-07-25 12:17:53 +04:00
addresses . Add ( jnInetAddress . getByAddress ( hostname , b ) ) ;
2007-07-12 12:40:32 +04:00
}
}
2007-11-26 14:01:29 +03:00
return addresses . ToArray ( ) ;
2007-07-12 12:40:32 +04:00
}
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 )
{
2007-07-12 12:46:25 +04:00
#if FIRST_PASS
return null ;
#else
2007-07-12 12:40:32 +04:00
try
{
2007-11-26 08:50:57 +03:00
return System . Net . Dns . GetHostEntry ( new System . Net . IPAddress ( addr ) ) . HostName ;
2007-07-12 12:40:32 +04:00
}
catch ( System . Net . Sockets . SocketException x )
{
throw new jnUnknownHostException ( x . Message ) ;
}
2007-07-12 12:46:25 +04:00
#endif
2007-07-12 12:40:32 +04:00
}
public static bool isReachable0 ( object thisInet4AddressImpl , byte [ ] addr , int timeout , byte [ ] ifaddr , int ttl )
{
2007-08-17 17:35:51 +04:00
// 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 ;
2007-07-12 12:40:32 +04:00
}
}
2007-12-18 14:05:30 +03:00
static class Inet6Address
2007-07-12 12:40:32 +04:00
{
public static void init ( )
{
}
}
2007-12-18 14:05:30 +03:00
static class Inet6AddressImpl
2007-07-12 12:40:32 +04:00
{
public static string getLocalHostName ( object thisInet6AddressImpl )
{
2007-07-12 12:46:25 +04:00
#if FIRST_PASS
return null ;
#else
2007-07-12 12:40:32 +04:00
try
{
return System . Net . Dns . GetHostName ( ) ;
}
catch ( System . Net . Sockets . SocketException x )
{
throw new jnUnknownHostException ( x . Message ) ;
}
2007-07-12 12:46:25 +04:00
#endif
2007-07-12 12:40:32 +04:00
}
public static object lookupAllHostAddr ( object thisInet6AddressImpl , string hostname )
{
#if FIRST_PASS
return null ;
#else
try
{
System . Net . IPAddress [ ] addr = System . Net . Dns . GetHostAddresses ( hostname ) ;
jnInetAddress [ ] addresses = new jnInetAddress [ addr . Length ] ;
for ( int i = 0 ; i < addr . Length ; i + + )
{
2007-07-25 12:17:53 +04:00
addresses [ i ] = jnInetAddress . getByAddress ( hostname , addr [ i ] . GetAddressBytes ( ) ) ;
2007-07-12 12:40:32 +04:00
}
return addresses ;
}
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 thisInet6AddressImpl , byte [ ] addr )
{
throw new NotImplementedException ( ) ;
}
public static bool isReachable0 ( object thisInet6AddressImpl , byte [ ] addr , int scope , int timeout , byte [ ] inf , int ttl , int if_scope )
{
throw new NotImplementedException ( ) ;
}
}
2007-12-18 14:05:30 +03:00
static class NetworkInterface
2007-07-12 12:40:32 +04:00
{
2007-07-25 12:17:53 +04:00
#if ! FIRST_PASS
private static NetworkInterfaceInfo cache ;
private static DateTime cachedSince ;
#endif
2007-07-24 18:33:59 +04:00
2007-07-12 12:40:32 +04:00
public static void init ( )
{
}
2007-07-24 18:33:59 +04:00
#if ! FIRST_PASS
private class NetworkInterfaceInfo
{
internal System . Net . NetworkInformation . NetworkInterface [ ] dotnetInterfaces ;
internal jnNetworkInterface [ ] javaInterfaces ;
}
private static NetworkInterfaceInfo GetInterfaces ( )
{
2007-07-25 12:17:53 +04:00
// Since many of the methods in java.net.NetworkInterface end up calling this method and the underlying stuff this is
// based on isn't very quick either, we cache the array for a couple of seconds.
if ( cache ! = null & & DateTime . UtcNow - cachedSince < new TimeSpan ( 0 , 0 , 5 ) )
{
return cache ;
}
2007-07-24 18:33:59 +04:00
System . Net . NetworkInformation . NetworkInterface [ ] ifaces = System . Net . NetworkInformation . NetworkInterface . GetAllNetworkInterfaces ( ) ;
jnNetworkInterface [ ] ret = new jnNetworkInterface [ ifaces . Length ] ;
int eth = 0 ;
int tr = 0 ;
int fddi = 0 ;
int lo = 0 ;
int ppp = 0 ;
int sl = 0 ;
int net = 0 ;
for ( int i = 0 ; i < ifaces . Length ; i + + )
{
string name ;
switch ( ifaces [ i ] . NetworkInterfaceType )
{
case System . Net . NetworkInformation . NetworkInterfaceType . Ethernet :
name = "eth" + eth + + ;
break ;
case System . Net . NetworkInformation . NetworkInterfaceType . TokenRing :
name = "tr" + tr + + ;
break ;
case System . Net . NetworkInformation . NetworkInterfaceType . Fddi :
name = "fddi" + fddi + + ;
break ;
case System . Net . NetworkInformation . NetworkInterfaceType . Loopback :
if ( lo > 0 )
{
continue ;
}
name = "lo" ;
lo + + ;
break ;
case System . Net . NetworkInformation . NetworkInterfaceType . Ppp :
name = "ppp" + ppp + + ;
break ;
case System . Net . NetworkInformation . NetworkInterfaceType . Slip :
name = "sl" + sl + + ;
break ;
default :
name = "net" + net + + ;
break ;
}
System . Net . NetworkInformation . UnicastIPAddressInformationCollection uipaic = ifaces [ i ] . GetIPProperties ( ) . UnicastAddresses ;
jnInetAddress [ ] addresses = new jnInetAddress [ uipaic . Count ] ;
for ( int j = 0 ; j < addresses . Length ; j + + )
{
2007-07-25 12:17:53 +04:00
// TODO for IPv6 addresses we should set the scope
2007-07-24 18:33:59 +04:00
addresses [ j ] = jnInetAddress . getByAddress ( uipaic [ j ] . Address . GetAddressBytes ( ) ) ;
}
2008-09-01 09:19:04 +04:00
ret [ i ] = new jnNetworkInterface ( name , i , addresses ) ;
2007-07-24 18:33:59 +04:00
// TODO should implement bindings
2008-09-01 09:19:04 +04:00
ret [ i ] . _set ( ifaces [ i ] . Description , new jnInterfaceAddress [ 0 ] , new jnNetworkInterface [ 0 ] ) ;
2007-07-24 18:33:59 +04:00
}
NetworkInterfaceInfo nii = new NetworkInterfaceInfo ( ) ;
nii . dotnetInterfaces = ifaces ;
nii . javaInterfaces = ret ;
2007-07-25 12:17:53 +04:00
cache = nii ;
cachedSince = DateTime . UtcNow ;
2007-07-24 18:33:59 +04:00
return nii ;
}
#endif
2007-07-12 12:40:32 +04:00
public static object getByIndex ( int index )
{
2007-07-24 18:33:59 +04:00
#if FIRST_PASS
return null ;
#else
jnNetworkInterface [ ] ifaces = GetInterfaces ( ) . javaInterfaces ;
if ( index < 0 | | index > = ifaces . Length )
{
return null ;
}
return ifaces [ index ] ;
#endif
2007-07-12 12:40:32 +04:00
}
public static object getAll ( )
{
2007-07-24 18:33:59 +04:00
#if FIRST_PASS
return null ;
#else
return GetInterfaces ( ) . javaInterfaces ;
#endif
2007-07-12 12:40:32 +04:00
}
public static object getByName0 ( string name )
{
2007-07-24 18:33:59 +04:00
#if FIRST_PASS
return null ;
#else
foreach ( jnNetworkInterface iface in GetInterfaces ( ) . javaInterfaces )
{
if ( iface . getName ( ) = = name )
{
return iface ;
}
}
return null ;
#endif
2007-07-12 12:40:32 +04:00
}
public static object getByInetAddress0 ( object addr )
{
2007-07-24 18:33:59 +04:00
#if FIRST_PASS
return null ;
#else
foreach ( jnNetworkInterface iface in GetInterfaces ( ) . javaInterfaces )
{
juEnumeration addresses = iface . getInetAddresses ( ) ;
while ( addresses . hasMoreElements ( ) )
{
if ( addresses . nextElement ( ) . Equals ( addr ) )
{
return iface ;
}
}
}
return null ;
#endif
2007-07-12 12:40:32 +04:00
}
public static long getSubnet0 ( string name , int ind )
{
2007-07-24 18:33:59 +04:00
// this method is not used by the java code (!)
return 0 ;
2007-07-12 12:40:32 +04:00
}
public static object getBroadcast0 ( string name , int ind )
{
2007-07-24 18:33:59 +04:00
// this method is not used by the java code (!)
return null ;
2007-07-12 12:40:32 +04:00
}
public static bool isUp0 ( string name , int ind )
{
2007-07-24 18:33:59 +04:00
#if FIRST_PASS
return false ;
#else
return GetInterfaces ( ) . dotnetInterfaces [ ind ] . OperationalStatus = = System . Net . NetworkInformation . OperationalStatus . Up ;
#endif
2007-07-12 12:40:32 +04:00
}
public static bool isLoopback0 ( string name , int ind )
{
2007-07-24 18:33:59 +04:00
#if FIRST_PASS
return false ;
#else
return GetInterfaces ( ) . dotnetInterfaces [ ind ] . NetworkInterfaceType = = System . Net . NetworkInformation . NetworkInterfaceType . Loopback ;
#endif
2007-07-12 12:40:32 +04:00
}
public static bool supportsMulticast0 ( string name , int ind )
{
2007-07-24 18:33:59 +04:00
#if FIRST_PASS
return false ;
#else
return GetInterfaces ( ) . dotnetInterfaces [ ind ] . SupportsMulticast ;
#endif
2007-07-12 12:40:32 +04:00
}
public static bool isP2P0 ( string name , int ind )
{
2007-07-24 18:33:59 +04:00
#if FIRST_PASS
return false ;
#else
switch ( GetInterfaces ( ) . dotnetInterfaces [ ind ] . NetworkInterfaceType )
{
case System . Net . NetworkInformation . NetworkInterfaceType . Ppp :
case System . Net . NetworkInformation . NetworkInterfaceType . Slip :
return true ;
default :
return false ;
}
#endif
2007-07-12 12:40:32 +04:00
}
public static byte [ ] getMacAddr0 ( byte [ ] inAddr , string name , int ind )
{
2007-07-24 18:33:59 +04:00
#if FIRST_PASS
return null ;
#else
return GetInterfaces ( ) . dotnetInterfaces [ ind ] . GetPhysicalAddress ( ) . GetAddressBytes ( ) ;
#endif
2007-07-12 12:40:32 +04:00
}
public static int getMTU0 ( string name , int ind )
{
2007-07-24 18:33:59 +04:00
#if FIRST_PASS
return 0 ;
#else
2007-07-25 12:17:53 +04:00
System . Net . NetworkInformation . IPv4InterfaceProperties props = GetInterfaces ( ) . dotnetInterfaces [ ind ] . GetIPProperties ( ) . GetIPv4Properties ( ) ;
return props = = null ? - 1 : props . Mtu ;
2007-07-24 18:33:59 +04:00
#endif
}
}
2007-07-12 12:40:32 +04:00
}
2007-08-15 16:04:24 +04:00
namespace nio
{
[System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.LinkDemand, UnmanagedCode = true)]
2007-12-18 14:05:30 +03:00
static class Bits
2007-08-15 16:04:24 +04:00
{
public static void copyFromByteArray ( object src , long srcPos , long dstAddr , long length )
{
byte [ ] byteArray = src as byte [ ] ;
if ( byteArray ! = null )
{
System . Runtime . InteropServices . Marshal . Copy ( byteArray , ( int ) srcPos , ( IntPtr ) dstAddr , ( int ) length ) ;
return ;
}
char [ ] charArray = src as char [ ] ;
if ( charArray ! = null )
{
System . Runtime . InteropServices . Marshal . Copy ( charArray , ( ( int ) srcPos ) > > 1 , ( IntPtr ) dstAddr , ( ( int ) length ) > > 1 ) ;
return ;
}
short [ ] shortArray = src as short [ ] ;
if ( shortArray ! = null )
{
System . Runtime . InteropServices . Marshal . Copy ( shortArray , ( ( int ) srcPos ) > > 1 , ( IntPtr ) dstAddr , ( ( int ) length ) > > 1 ) ;
return ;
}
int [ ] intArray = src as int [ ] ;
if ( intArray ! = null )
{
System . Runtime . InteropServices . Marshal . Copy ( intArray , ( ( int ) srcPos ) > > 2 , ( IntPtr ) dstAddr , ( ( int ) length ) > > 2 ) ;
return ;
}
float [ ] floatArray = src as float [ ] ;
if ( floatArray ! = null )
{
System . Runtime . InteropServices . Marshal . Copy ( floatArray , ( ( int ) srcPos ) > > 2 , ( IntPtr ) dstAddr , ( ( int ) length ) > > 2 ) ;
return ;
}
long [ ] longArray = src as long [ ] ;
if ( longArray ! = null )
{
System . Runtime . InteropServices . Marshal . Copy ( longArray , ( ( int ) srcPos ) > > 3 , ( IntPtr ) dstAddr , ( ( int ) length ) > > 3 ) ;
return ;
}
double [ ] doubleArray = src as double [ ] ;
if ( doubleArray ! = null )
{
System . Runtime . InteropServices . Marshal . Copy ( doubleArray , ( ( int ) srcPos ) > > 3 , ( IntPtr ) dstAddr , ( ( int ) length ) > > 3 ) ;
return ;
}
}
public static void copyToByteArray ( long srcAddr , object dst , long dstPos , long length )
{
byte [ ] byteArray = dst as byte [ ] ;
if ( byteArray ! = null )
{
System . Runtime . InteropServices . Marshal . Copy ( ( IntPtr ) srcAddr , byteArray , ( int ) dstPos , ( int ) length ) ;
return ;
}
char [ ] charArray = dst as char [ ] ;
if ( charArray ! = null )
{
System . Runtime . InteropServices . Marshal . Copy ( ( IntPtr ) srcAddr , charArray , ( ( int ) dstPos ) > > 1 , ( ( int ) length ) > > 1 ) ;
return ;
}
short [ ] shortArray = dst as short [ ] ;
if ( shortArray ! = null )
{
System . Runtime . InteropServices . Marshal . Copy ( ( IntPtr ) srcAddr , shortArray , ( ( int ) dstPos ) > > 1 , ( ( int ) length ) > > 1 ) ;
return ;
}
int [ ] intArray = dst as int [ ] ;
if ( intArray ! = null )
{
System . Runtime . InteropServices . Marshal . Copy ( ( IntPtr ) srcAddr , intArray , ( ( int ) dstPos ) > > 2 , ( ( int ) length ) > > 2 ) ;
return ;
}
float [ ] floatArray = dst as float [ ] ;
if ( floatArray ! = null )
{
System . Runtime . InteropServices . Marshal . Copy ( ( IntPtr ) srcAddr , floatArray , ( ( int ) dstPos ) > > 2 , ( ( int ) length ) > > 2 ) ;
return ;
}
long [ ] longArray = dst as long [ ] ;
if ( longArray ! = null )
{
System . Runtime . InteropServices . Marshal . Copy ( ( IntPtr ) srcAddr , longArray , ( ( int ) dstPos ) > > 3 , ( ( int ) length ) > > 3 ) ;
return ;
}
double [ ] doubleArray = dst as double [ ] ;
if ( doubleArray ! = null )
{
System . Runtime . InteropServices . Marshal . Copy ( ( IntPtr ) srcAddr , doubleArray , ( ( int ) dstPos ) > > 3 , ( ( int ) length ) > > 3 ) ;
return ;
}
}
public static void copyFromShortArray ( object src , long srcPos , long dstAddr , long length )
{
#if ! FIRST_PASS
short [ ] shortArray = src as short [ ] ;
if ( shortArray ! = null )
{
int index = ( ( int ) srcPos ) > > 1 ;
while ( length > 0 )
{
short v = jlShort . reverseBytes ( shortArray [ index + + ] ) ;
System . Runtime . InteropServices . Marshal . WriteInt16 ( ( IntPtr ) dstAddr , v ) ;
dstAddr + = 2 ;
length - = 2 ;
}
}
else
{
char [ ] charArray = ( char [ ] ) src ;
int index = ( ( int ) srcPos ) > > 1 ;
while ( length > 0 )
{
short v = jlShort . reverseBytes ( ( short ) charArray [ index + + ] ) ;
System . Runtime . InteropServices . Marshal . WriteInt16 ( ( IntPtr ) dstAddr , v ) ;
dstAddr + = 2 ;
length - = 2 ;
}
}
#endif
}
public static void copyToShortArray ( long srcAddr , object dst , long dstPos , long length )
{
#if ! FIRST_PASS
short [ ] shortArray = dst as short [ ] ;
if ( shortArray ! = null )
{
int index = ( ( int ) dstPos ) > > 1 ;
while ( length > 0 )
{
short v = System . Runtime . InteropServices . Marshal . ReadInt16 ( ( IntPtr ) srcAddr ) ;
shortArray [ index + + ] = jlShort . reverseBytes ( v ) ;
srcAddr + = 2 ;
length - = 2 ;
}
}
else
{
char [ ] charArray = ( char [ ] ) dst ;
int index = ( ( int ) dstPos ) > > 1 ;
while ( length > 0 )
{
short v = System . Runtime . InteropServices . Marshal . ReadInt16 ( ( IntPtr ) srcAddr ) ;
charArray [ index + + ] = ( char ) jlShort . reverseBytes ( v ) ;
srcAddr + = 2 ;
length - = 2 ;
}
}
#endif
}
public static void copyFromIntArray ( object src , long srcPos , long dstAddr , long length )
{
#if ! FIRST_PASS
int [ ] intArray = src as int [ ] ;
if ( intArray ! = null )
{
int index = ( ( int ) srcPos ) > > 2 ;
while ( length > 0 )
{
int v = jlInteger . reverseBytes ( intArray [ index + + ] ) ;
System . Runtime . InteropServices . Marshal . WriteInt32 ( ( IntPtr ) dstAddr , v ) ;
dstAddr + = 4 ;
length - = 4 ;
}
}
else
{
float [ ] floatArray = ( float [ ] ) src ;
int index = ( ( int ) srcPos ) > > 2 ;
while ( length > 0 )
{
int v = jlInteger . reverseBytes ( jlFloat . floatToRawIntBits ( floatArray [ index + + ] ) ) ;
System . Runtime . InteropServices . Marshal . WriteInt32 ( ( IntPtr ) dstAddr , v ) ;
dstAddr + = 4 ;
length - = 4 ;
}
}
#endif
}
public static void copyToIntArray ( long srcAddr , object dst , long dstPos , long length )
{
#if ! FIRST_PASS
int [ ] intArray = dst as int [ ] ;
if ( intArray ! = null )
{
int index = ( ( int ) dstPos ) > > 2 ;
while ( length > 0 )
{
int v = System . Runtime . InteropServices . Marshal . ReadInt32 ( ( IntPtr ) srcAddr ) ;
intArray [ index + + ] = jlInteger . reverseBytes ( v ) ;
srcAddr + = 4 ;
length - = 4 ;
}
}
else
{
float [ ] floatArray = ( float [ ] ) dst ;
int index = ( ( int ) dstPos ) > > 2 ;
while ( length > 0 )
{
int v = System . Runtime . InteropServices . Marshal . ReadInt32 ( ( IntPtr ) srcAddr ) ;
floatArray [ index + + ] = jlFloat . intBitsToFloat ( jlInteger . reverseBytes ( v ) ) ;
srcAddr + = 4 ;
length - = 4 ;
}
}
#endif
}
public static void copyFromLongArray ( object src , long srcPos , long dstAddr , long length )
{
#if ! FIRST_PASS
long [ ] longArray = src as long [ ] ;
if ( longArray ! = null )
{
int index = ( ( int ) srcPos ) > > 3 ;
while ( length > 0 )
{
long v = jlLong . reverseBytes ( longArray [ index + + ] ) ;
System . Runtime . InteropServices . Marshal . WriteInt64 ( ( IntPtr ) dstAddr , v ) ;
dstAddr + = 8 ;
length - = 8 ;
}
}
else
{
double [ ] doubleArray = ( double [ ] ) src ;
int index = ( ( int ) srcPos ) > > 3 ;
while ( length > 0 )
{
long v = jlLong . reverseBytes ( BitConverter . DoubleToInt64Bits ( doubleArray [ index + + ] ) ) ;
System . Runtime . InteropServices . Marshal . WriteInt64 ( ( IntPtr ) dstAddr , v ) ;
dstAddr + = 8 ;
length - = 8 ;
}
}
#endif
}
public static void copyToLongArray ( long srcAddr , object dst , long dstPos , long length )
{
#if ! FIRST_PASS
long [ ] longArray = dst as long [ ] ;
if ( longArray ! = null )
{
int index = ( ( int ) dstPos ) > > 3 ;
while ( length > 0 )
{
long v = System . Runtime . InteropServices . Marshal . ReadInt64 ( ( IntPtr ) srcAddr ) ;
longArray [ index + + ] = jlLong . reverseBytes ( v ) ;
srcAddr + = 8 ;
length - = 8 ;
}
}
else
{
double [ ] doubleArray = ( double [ ] ) dst ;
int index = ( ( int ) dstPos ) > > 3 ;
while ( length > 0 )
{
long v = System . Runtime . InteropServices . Marshal . ReadInt64 ( ( IntPtr ) srcAddr ) ;
doubleArray [ index + + ] = BitConverter . Int64BitsToDouble ( jlLong . reverseBytes ( v ) ) ;
srcAddr + = 8 ;
length - = 8 ;
}
}
#endif
}
}
[System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.LinkDemand, UnmanagedCode = true)]
2007-12-18 14:05:30 +03:00
static class MappedByteBuffer
2007-08-15 16:04:24 +04:00
{
private static volatile int bogusField ;
public static bool isLoaded0 ( object thisMappedByteBuffer , long address , long length )
{
// on Windows, JDK simply returns false, so we can get away with that too.
return false ;
}
public static int load0 ( object thisMappedByteBuffer , long address , long length , int pageSize )
{
2008-05-20 11:43:42 +04:00
int bogus = bogusField ;
2007-08-15 16:04:24 +04:00
while ( length > 0 )
{
// touch a byte in every page
bogus + = System . Runtime . InteropServices . Marshal . ReadByte ( ( IntPtr ) address ) ;
length - = pageSize ;
address + = pageSize ;
}
// do a volatile store of the sum of the bytes to make sure the reads don't get optimized out
bogusField = bogus ;
2007-11-26 15:51:21 +03:00
GC . KeepAlive ( thisMappedByteBuffer ) ;
2007-08-15 16:04:24 +04:00
return 0 ;
}
public static void force0 ( object thisMappedByteBuffer , long address , long length )
{
if ( JVM . IsUnix )
{
ikvm_msync ( ( IntPtr ) address , ( int ) length ) ;
2007-11-26 15:51:21 +03:00
GC . KeepAlive ( thisMappedByteBuffer ) ;
2007-08-15 16:04:24 +04:00
}
else
{
// according to the JDK sources, FlushViewOfFile can fail with an ERROR_LOCK_VIOLATION error,
// so like the JDK, we retry up to three times if that happens.
for ( int i = 0 ; i < 3 ; i + + )
{
if ( FlushViewOfFile ( ( IntPtr ) address , ( IntPtr ) length ) ! = 0 )
{
2007-11-26 15:51:21 +03:00
GC . KeepAlive ( thisMappedByteBuffer ) ;
2007-08-15 16:04:24 +04:00
return ;
}
const int ERROR_LOCK_VIOLATION = 33 ;
if ( System . Runtime . InteropServices . Marshal . GetLastWin32Error ( ) ! = ERROR_LOCK_VIOLATION )
{
break ;
}
}
#if ! FIRST_PASS
throw new jiIOException ( "Flush failed" ) ;
#endif
}
}
[System.Runtime.InteropServices.DllImport("kernel32", SetLastError = true)]
private static extern int FlushViewOfFile ( IntPtr lpBaseAddress , IntPtr dwNumberOfBytesToFlush ) ;
[System.Runtime.InteropServices.DllImport("ikvm-native")]
private static extern int ikvm_msync ( IntPtr address , int size ) ;
}
}
2007-07-11 11:11:35 +04:00
namespace security
{
2007-12-18 14:05:30 +03:00
static class AccessController
2007-07-11 11:11:35 +04:00
{
2009-01-02 13:44:05 +03:00
public static object getStackAccessControlContext ( object context , object callerID )
2007-07-11 11:11:35 +04:00
{
#if FIRST_PASS
return null ;
#else
object previous_protection_domain = null ;
object privileged_context = null ;
bool is_privileged = false ;
object protection_domain = null ;
StackTrace stack = new StackTrace ( 1 ) ;
2007-11-26 14:01:29 +03:00
List < ProtectionDomain > array = new List < ProtectionDomain > ( ) ;
2007-07-11 11:11:35 +04:00
for ( int i = 0 ; i < stack . FrameCount ; i + + )
{
MethodBase method = stack . GetFrame ( i ) . GetMethod ( ) ;
2007-08-10 17:04:21 +04:00
if ( method . DeclaringType = = typeof ( AccessController )
2007-07-11 11:11:35 +04:00
& & method . Name = = "doPrivileged" )
{
is_privileged = true ;
2009-01-02 13:44:05 +03:00
privileged_context = context ;
global :: java . lang . Class caller = ( ( global :: ikvm . @internal . CallerID ) callerID ) . getCallerClass ( ) ;
protection_domain = caller = = null ? null : java . lang . Class . getProtectionDomain0 ( caller ) ;
2007-07-11 11:11:35 +04:00
}
else
{
protection_domain = GetProtectionDomainFromType ( method . DeclaringType ) ;
}
if ( previous_protection_domain ! = protection_domain & & protection_domain ! = null )
{
previous_protection_domain = protection_domain ;
2007-11-26 14:01:29 +03:00
array . Add ( ( ProtectionDomain ) protection_domain ) ;
2007-07-11 11:11:35 +04:00
}
if ( is_privileged )
{
break ;
}
}
if ( array . Count = = 0 )
{
if ( is_privileged & & privileged_context = = null )
{
return null ;
}
return CreateAccessControlContext ( null , is_privileged , privileged_context ) ;
}
2007-11-26 14:01:29 +03:00
return CreateAccessControlContext ( array . ToArray ( ) , is_privileged , privileged_context ) ;
2007-07-11 11:11:35 +04:00
#endif
}
#if ! FIRST_PASS
private static object CreateAccessControlContext ( ProtectionDomain [ ] context , bool is_privileged , object privileged_context )
{
2008-09-01 09:19:04 +04:00
jsAccessControlContext acc = new jsAccessControlContext ( context , is_privileged ) ;
acc . _privilegedContext ( ( jsAccessControlContext ) privileged_context ) ;
return acc ;
2007-07-11 11:11:35 +04:00
}
private static object GetProtectionDomainFromType ( Type type )
{
if ( type = = null
| | type . Assembly = = typeof ( object ) . Assembly
| | type . Assembly = = typeof ( AccessController ) . Assembly
2007-12-27 18:16:49 +03:00
| | type . Assembly = = java . lang . SecurityManager . jniAssembly
2007-07-11 11:11:35 +04:00
| | type . Assembly = = typeof ( jlThread ) . Assembly )
{
return null ;
}
TypeWrapper tw = ClassLoaderWrapper . GetWrapperFromType ( type ) ;
if ( tw ! = null )
{
return java . lang . Class . getProtectionDomain0 ( tw . ClassObject ) ;
}
return null ;
}
#endif
public static object getInheritedAccessControlContext ( )
{
#if FIRST_PASS
return null ;
#else
2008-09-01 09:19:04 +04:00
return jlThread . currentThread ( ) . inheritedAccessControlContext ;
2007-07-11 11:11:35 +04:00
#endif
}
}
}
2007-06-20 18:15:27 +04:00
namespace util
{
2007-06-22 09:53:47 +04:00
namespace logging
{
2007-12-18 14:05:30 +03:00
static class FileHandler
2007-06-22 09:53:47 +04:00
{
public static bool isSetUID ( )
{
// TODO
return false ;
}
}
}
2007-06-21 14:32:51 +04:00
namespace prefs
{
2007-12-18 14:05:30 +03:00
static class FileSystemPreferences
2007-06-21 14:32:51 +04:00
{
public static int chmod ( string filename , int permission )
{
// TODO
return 0 ;
}
public static int [ ] lockFile0 ( string filename , int permission , bool shared )
{
// TODO
return new int [ ] { 1 , 0 } ;
}
public static int unlockFile0 ( int fd )
{
// TODO
return 0 ;
}
}
2007-12-18 14:05:30 +03:00
static class WindowsPreferences
2007-06-21 14:32:51 +04:00
{
// HACK we currently support only 16 handles at a time
private static Microsoft . Win32 . RegistryKey [ ] keys = new Microsoft . Win32 . RegistryKey [ 16 ] ;
private static Microsoft . Win32 . RegistryKey MapKey ( int hKey )
{
switch ( hKey )
{
case unchecked ( ( int ) 0x80000001 ) :
return Microsoft . Win32 . Registry . CurrentUser ;
case unchecked ( ( int ) 0x80000002 ) :
return Microsoft . Win32 . Registry . LocalMachine ;
default :
return keys [ hKey - 1 ] ;
}
}
private static int AllocHandle ( Microsoft . Win32 . RegistryKey key )
{
lock ( keys )
{
if ( key ! = null )
{
for ( int i = 0 ; i < keys . Length ; i + + )
{
if ( keys [ i ] = = null )
{
keys [ i ] = key ;
return i + 1 ;
}
}
}
return 0 ;
}
}
private static string BytesToString ( byte [ ] bytes )
{
int len = bytes . Length ;
if ( bytes [ len - 1 ] = = 0 )
{
len - - ;
}
return Encoding . ASCII . GetString ( bytes , 0 , len ) ;
}
private static byte [ ] StringToBytes ( string str )
{
if ( str . Length = = 0 | | str [ str . Length - 1 ] ! = 0 )
{
str + = ' \ u0000 ' ;
}
return Encoding . ASCII . GetBytes ( str ) ;
}
public static int [ ] WindowsRegOpenKey ( int hKey , byte [ ] subKey , int securityMask )
{
bool writable = ( securityMask & 0x30006 ) ! = 0 ;
Microsoft . Win32 . RegistryKey resultKey = null ;
int error = 0 ;
try
{
resultKey = MapKey ( hKey ) . OpenSubKey ( BytesToString ( subKey ) , writable ) ;
}
catch ( System . Security . SecurityException )
{
error = 5 ;
}
catch ( UnauthorizedAccessException )
{
error = 5 ;
}
return new int [ ] { AllocHandle ( resultKey ) , error } ;
}
public static int WindowsRegCloseKey ( int hKey )
{
keys [ hKey - 1 ] . Close ( ) ;
lock ( keys )
{
keys [ hKey - 1 ] = null ;
}
return 0 ;
}
public static int [ ] WindowsRegCreateKeyEx ( int hKey , byte [ ] subKey )
{
Microsoft . Win32 . RegistryKey resultKey = null ;
int error = 0 ;
int disposition = - 1 ;
try
{
Microsoft . Win32 . RegistryKey key = MapKey ( hKey ) ;
string name = BytesToString ( subKey ) ;
resultKey = key . OpenSubKey ( name ) ;
disposition = 2 ;
if ( resultKey = = null )
{
resultKey = key . CreateSubKey ( name ) ;
disposition = 1 ;
}
}
catch ( System . Security . SecurityException )
{
error = 5 ;
}
catch ( UnauthorizedAccessException )
{
error = 5 ;
}
return new int [ ] { AllocHandle ( resultKey ) , error , disposition } ;
}
public static int WindowsRegDeleteKey ( int hKey , byte [ ] subKey )
{
try
{
MapKey ( hKey ) . DeleteSubKey ( BytesToString ( subKey ) ) ;
return 0 ;
}
catch ( System . Security . SecurityException )
{
return 5 ;
}
}
public static int WindowsRegFlushKey ( int hKey )
{
MapKey ( hKey ) . Flush ( ) ;
return 0 ;
}
public static byte [ ] WindowsRegQueryValueEx ( int hKey , byte [ ] valueName )
{
try
{
string value = MapKey ( hKey ) . GetValue ( BytesToString ( valueName ) ) as string ;
if ( value = = null )
{
return null ;
}
return StringToBytes ( value ) ;
}
catch ( System . Security . SecurityException )
{
return null ;
}
catch ( UnauthorizedAccessException )
{
return null ;
}
}
public static int WindowsRegSetValueEx ( int hKey , byte [ ] valueName , byte [ ] data )
{
if ( valueName = = null | | data = = null )
{
return - 1 ;
}
try
{
MapKey ( hKey ) . SetValue ( BytesToString ( valueName ) , BytesToString ( data ) ) ;
return 0 ;
}
catch ( System . Security . SecurityException )
{
return 5 ;
}
catch ( UnauthorizedAccessException )
{
return 5 ;
}
}
public static int WindowsRegDeleteValue ( int hKey , byte [ ] valueName )
{
try
{
MapKey ( hKey ) . DeleteValue ( BytesToString ( valueName ) ) ;
return 0 ;
}
catch ( System . Security . SecurityException )
{
return 5 ;
}
catch ( UnauthorizedAccessException )
{
return 5 ;
}
}
public static int [ ] WindowsRegQueryInfoKey ( int hKey )
{
int [ ] result = new int [ 5 ] { - 1 , - 1 , - 1 , - 1 , - 1 } ;
try
{
Microsoft . Win32 . RegistryKey key = MapKey ( hKey ) ;
result [ 0 ] = key . SubKeyCount ;
result [ 1 ] = 0 ;
result [ 2 ] = key . ValueCount ;
foreach ( string s in key . GetSubKeyNames ( ) )
{
result [ 3 ] = Math . Max ( result [ 3 ] , s . Length ) ;
}
foreach ( string s in key . GetValueNames ( ) )
{
result [ 4 ] = Math . Max ( result [ 4 ] , s . Length ) ;
}
}
catch ( System . Security . SecurityException )
{
result [ 1 ] = 5 ;
}
catch ( UnauthorizedAccessException )
{
result [ 1 ] = 5 ;
}
return result ;
}
public static byte [ ] WindowsRegEnumKeyEx ( int hKey , int subKeyIndex , int maxKeyLength )
{
try
{
return StringToBytes ( MapKey ( hKey ) . GetSubKeyNames ( ) [ subKeyIndex ] ) ;
}
catch ( System . Security . SecurityException )
{
return null ;
}
catch ( UnauthorizedAccessException )
{
return null ;
}
}
public static byte [ ] WindowsRegEnumValue ( int hKey , int valueIndex , int maxValueNameLength )
{
try
{
return StringToBytes ( MapKey ( hKey ) . GetValueNames ( ) [ valueIndex ] ) ;
}
catch ( System . Security . SecurityException )
{
return null ;
}
catch ( UnauthorizedAccessException )
{
return null ;
}
}
}
}
2007-07-12 12:40:32 +04:00
namespace jar
{
2007-12-18 14:05:30 +03:00
static class JarFile
2007-07-12 12:40:32 +04:00
{
public static string [ ] getMetaInfEntryNames ( object thisJarFile )
{
#if FIRST_PASS
return null ;
#else
juzZipFile zf = ( juzZipFile ) thisJarFile ;
juEnumeration entries = zf . entries ( ) ;
2007-11-26 14:01:29 +03:00
List < string > list = null ;
2007-07-12 12:40:32 +04:00
while ( entries . hasMoreElements ( ) )
{
juzZipEntry entry = ( juzZipEntry ) entries . nextElement ( ) ;
2008-07-04 09:40:54 +04:00
if ( entry . getName ( ) . StartsWith ( "META-INF/" , StringComparison . OrdinalIgnoreCase ) )
2007-07-12 12:40:32 +04:00
{
if ( list = = null )
{
2007-11-26 14:01:29 +03:00
list = new List < string > ( ) ;
2007-07-12 12:40:32 +04:00
}
list . Add ( entry . getName ( ) ) ;
}
}
2007-11-26 14:01:29 +03:00
return list = = null ? null : list . ToArray ( ) ;
2007-07-12 12:40:32 +04:00
#endif
}
}
}
2007-12-18 14:05:30 +03:00
static class TimeZone
2007-06-20 18:15:27 +04:00
{
public static string getSystemTimeZoneID ( string javaHome , string country )
{
2007-06-27 10:14:54 +04:00
// HACK this is very lame and probably won't work on localized windows versions
// (the switch was generated from the contents of $JAVA_HOME/lib/tzmappings)
switch ( SystemTimeZone . CurrentTimeZone . StandardName )
{
case "Romance" :
case "Romance Standard Time" :
return "Europe/Paris" ;
case "Warsaw" :
return "Europe/Warsaw" ;
case "Central Europe" :
case "Central Europe Standard Time" :
case "Prague Bratislava" :
return "Europe/Prague" ;
case "W. Central Africa Standard Time" :
return "Africa/Luanda" ;
case "FLE" :
case "FLE Standard Time" :
return "Europe/Helsinki" ;
case "GFT" :
case "GFT Standard Time" :
case "GTB" :
case "GTB Standard Time" :
return "Europe/Athens" ;
case "Israel" :
case "Israel Standard Time" :
return "Asia/Jerusalem" ;
case "Arab" :
case "Arab Standard Time" :
return "Asia/Riyadh" ;
case "Arabic Standard Time" :
return "Asia/Baghdad" ;
case "E. Africa" :
case "E. Africa Standard Time" :
return "Africa/Nairobi" ;
case "Saudi Arabia" :
case "Saudi Arabia Standard Time" :
return "Asia/Riyadh" ;
case "Iran" :
case "Iran Standard Time" :
return "Asia/Tehran" ;
case "Afghanistan" :
case "Afghanistan Standard Time" :
return "Asia/Kabul" ;
case "India" :
case "India Standard Time" :
return "Asia/Calcutta" ;
case "Myanmar Standard Time" :
return "Asia/Rangoon" ;
case "Nepal Standard Time" :
return "Asia/Katmandu" ;
case "Sri Lanka" :
case "Sri Lanka Standard Time" :
return "Asia/Colombo" ;
case "Beijing" :
case "China" :
case "China Standard Time" :
return "Asia/Shanghai" ;
case "AUS Central" :
case "AUS Central Standard Time" :
return "Australia/Darwin" ;
case "Cen. Australia" :
case "Cen. Australia Standard Time" :
return "Australia/Adelaide" ;
case "Vladivostok" :
case "Vladivostok Standard Time" :
return "Asia/Vladivostok" ;
case "West Pacific" :
case "West Pacific Standard Time" :
return "Pacific/Guam" ;
case "E. South America" :
case "E. South America Standard Time" :
return "America/Sao_Paulo" ;
case "Greenland Standard Time" :
return "America/Godthab" ;
case "Newfoundland" :
case "Newfoundland Standard Time" :
return "America/St_Johns" ;
case "Pacific SA" :
case "Pacific SA Standard Time" :
return "America/Santiago" ;
case "SA Western" :
case "SA Western Standard Time" :
return "America/Caracas" ;
case "SA Pacific" :
case "SA Pacific Standard Time" :
return "America/Bogota" ;
case "US Eastern" :
case "US Eastern Standard Time" :
return "America/Indianapolis" ;
case "Central America Standard Time" :
return "America/Regina" ;
case "Mexico" :
case "Mexico Standard Time" :
return "America/Mexico_City" ;
case "Canada Central" :
case "Canada Central Standard Time" :
return "America/Regina" ;
case "US Mountain" :
case "US Mountain Standard Time" :
return "America/Phoenix" ;
case "GMT" :
case "GMT Standard Time" :
return "Europe/London" ;
case "Ekaterinburg" :
case "Ekaterinburg Standard Time" :
return "Asia/Yekaterinburg" ;
case "West Asia" :
case "West Asia Standard Time" :
return "Asia/Karachi" ;
case "Central Asia" :
case "Central Asia Standard Time" :
return "Asia/Dhaka" ;
case "N. Central Asia Standard Time" :
return "Asia/Novosibirsk" ;
case "Bangkok" :
case "Bangkok Standard Time" :
return "Asia/Bangkok" ;
case "North Asia Standard Time" :
return "Asia/Krasnoyarsk" ;
case "SE Asia" :
case "SE Asia Standard Time" :
return "Asia/Bangkok" ;
case "North Asia East Standard Time" :
return "Asia/Ulaanbaatar" ;
case "Singapore" :
case "Singapore Standard Time" :
return "Asia/Singapore" ;
case "Taipei" :
case "Taipei Standard Time" :
return "Asia/Taipei" ;
case "W. Australia" :
case "W. Australia Standard Time" :
return "Australia/Perth" ;
case "Korea" :
case "Korea Standard Time" :
return "Asia/Seoul" ;
case "Tokyo" :
case "Tokyo Standard Time" :
return "Asia/Tokyo" ;
case "Yakutsk" :
case "Yakutsk Standard Time" :
return "Asia/Yakutsk" ;
case "Central European" :
case "Central European Standard Time" :
return "Europe/Belgrade" ;
case "W. Europe" :
case "W. Europe Standard Time" :
return "Europe/Berlin" ;
case "Tasmania" :
case "Tasmania Standard Time" :
return "Australia/Hobart" ;
case "AUS Eastern" :
case "AUS Eastern Standard Time" :
return "Australia/Sydney" ;
case "E. Australia" :
case "E. Australia Standard Time" :
return "Australia/Brisbane" ;
case "Sydney Standard Time" :
return "Australia/Sydney" ;
case "Central Pacific" :
case "Central Pacific Standard Time" :
return "Pacific/Guadalcanal" ;
case "Dateline" :
case "Dateline Standard Time" :
return "GMT-1200" ;
case "Fiji" :
case "Fiji Standard Time" :
return "Pacific/Fiji" ;
case "Samoa" :
case "Samoa Standard Time" :
return "Pacific/Apia" ;
case "Hawaiian" :
case "Hawaiian Standard Time" :
return "Pacific/Honolulu" ;
case "Alaskan" :
case "Alaskan Standard Time" :
return "America/Anchorage" ;
case "Pacific" :
case "Pacific Standard Time" :
return "America/Los_Angeles" ;
case "Mexico Standard Time 2" :
return "America/Chihuahua" ;
case "Mountain" :
case "Mountain Standard Time" :
return "America/Denver" ;
case "Central" :
case "Central Standard Time" :
return "America/Chicago" ;
case "Eastern" :
case "Eastern Standard Time" :
return "America/New_York" ;
case "E. Europe" :
case "E. Europe Standard Time" :
return "Europe/Minsk" ;
case "Egypt" :
case "Egypt Standard Time" :
return "Africa/Cairo" ;
case "South Africa" :
case "South Africa Standard Time" :
return "Africa/Harare" ;
case "Atlantic" :
case "Atlantic Standard Time" :
return "America/Halifax" ;
case "SA Eastern" :
case "SA Eastern Standard Time" :
return "America/Buenos_Aires" ;
case "Mid-Atlantic" :
case "Mid-Atlantic Standard Time" :
return "Atlantic/South_Georgia" ;
case "Azores" :
case "Azores Standard Time" :
return "Atlantic/Azores" ;
case "Cape Verde Standard Time" :
return "Atlantic/Cape_Verde" ;
case "Russian" :
case "Russian Standard Time" :
return "Europe/Moscow" ;
case "New Zealand" :
case "New Zealand Standard Time" :
return "Pacific/Auckland" ;
case "Tonga Standard Time" :
return "Pacific/Tongatapu" ;
case "Arabian" :
case "Arabian Standard Time" :
return "Asia/Muscat" ;
case "Caucasus" :
case "Caucasus Standard Time" :
return "Asia/Yerevan" ;
case "Greenwich" :
case "Greenwich Standard Time" :
return "GMT" ;
case "Central Brazilian Standard Time" :
return "America/Manaus" ;
case "Central Standard Time (Mexico)" :
return "America/Mexico_City" ;
case "Georgian Standard Time" :
return "Asia/Tbilisi" ;
case "Mountain Standard Time (Mexico)" :
return "America/Chihuahua" ;
case "Namibia Standard Time" :
return "Africa/Windhoek" ;
case "Pacific Standard Time (Mexico)" :
return "America/Tijuana" ;
case "Western Brazilian Standard Time" :
return "America/Rio_Branco" ;
case "Azerbaijan Standard Time" :
return "Asia/Baku" ;
case "Jordan Standard Time" :
return "Asia/Amman" ;
case "Middle East Standard Time" :
return "Asia/Beirut" ;
default :
// this means fall back to GMT offset
return null ;
}
2007-06-20 18:15:27 +04:00
}
public static string getSystemGMTOffsetID ( )
{
TimeSpan sp = SystemTimeZone . CurrentTimeZone . GetUtcOffset ( DateTime . Now ) ;
int hours = sp . Hours ;
int mins = sp . Minutes ;
if ( hours > = 0 & & mins > = 0 )
{
return String . Format ( "GMT+{0:D2}:{1:D2}" , hours , mins ) ;
}
else
{
return String . Format ( "GMT-{0:D2}:{1:D2}" , - hours , - mins ) ;
}
}
}
}
2007-05-28 14:15:23 +04:00
}
2009-05-03 22:44:22 +04:00
namespace IKVM.NativeCode.sun.awt
{
static class KeyboardFocusManagerPeerImpl
{
public static object getNativeFocusedWindow ( ) { return null ; }
public static object getNativeFocusOwner ( ) { return null ; }
public static void clearNativeGlobalFocusOwner ( object activeWindow ) { }
}
2009-05-22 23:59:24 +04:00
static class SunToolkit
{
public static void closeSplashScreen ( ) { }
}
2009-05-03 22:44:22 +04:00
}
2009-06-06 16:32:47 +04:00
namespace IKVM.NativeCode.sun.awt.shell
{
/// <summary>
/// This class should use only on Windows that we can access shell32.dll
/// </summary>
static class Win32ShellFolder2
{
2009-06-28 00:43:42 +04:00
private const uint SHGFI_LARGEICON = 0x0 ;
private const uint SHGFI_SMALLICON = 0x1 ;
private const uint SHGFI_ICON = 0x100 ;
2009-06-06 16:32:47 +04:00
private const uint SHGFI_TYPENAME = 0x400 ;
2009-06-27 19:42:17 +04:00
private const uint SHGFI_ATTRIBUTES = 0x800 ;
2009-06-06 16:32:47 +04:00
private struct SHFILEINFO
{
public IntPtr hIcon ;
public IntPtr iIcon ;
public uint dwAttributes ;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szDisplayName ;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
public string szTypeName ;
} ;
[DllImport("shell32.dll")]
2009-06-27 19:42:17 +04:00
private static extern int FindExecutable ( string lpFile , string lpDirectory , StringBuilder lpResult ) ;
2009-06-06 16:32:47 +04:00
[DllImport("shell32.dll")]
private static extern IntPtr SHGetFileInfo ( string pszPath , uint dwFileAttributes , ref SHFILEINFO psfi , uint cbSizeFileInfo , uint uFlags ) ;
2009-06-27 19:42:17 +04:00
[DllImport("user32.dll", EntryPoint = "LoadImage")]
private static extern IntPtr LoadImageID ( IntPtr hInstance , int uID , uint type , int width , int height , int load ) ;
[DllImport("user32.dll", EntryPoint = "LoadImage")]
private static extern IntPtr LoadImageName ( IntPtr hInstance , string lpszName , uint type , int width , int height , int load ) ;
[DllImport("kernel32.dll")]
static extern IntPtr LoadLibrary ( string Library ) ;
[DllImport("gdi32.dll", EntryPoint = "DeleteObject")]
public static extern bool DeleteObject ( IntPtr hDc ) ;
private const uint IMAGE_BITMAP = 0 ;
private const uint IMAGE_ICON = 1 ;
2009-06-06 16:32:47 +04:00
/// <summary>
/// Get the program to execute or open the file. If it is a exe then it is self
/// </summary>
/// <param name="path">path to the file</param>
/// <returns></returns>
public static string getExecutableType ( string path )
{
StringBuilder objResultBuffer = new StringBuilder ( 1024 ) ;
2009-06-27 19:42:17 +04:00
int result = FindExecutable ( path , path , objResultBuffer ) ;
if ( result > = 32 )
2009-06-06 16:32:47 +04:00
{
return objResultBuffer . ToString ( ) ;
}
return null ;
}
/// <summary>
/// Get the type of a file or folder. On a file it depends on its extension.
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public static string getFolderType ( string path )
{
SHFILEINFO shinfo = new SHFILEINFO ( ) ;
if ( 0 = = SHGetFileInfo ( path , 0 , ref shinfo , ( uint ) Marshal . SizeOf ( shinfo ) , SHGFI_TYPENAME ) . ToInt32 ( ) )
{
return null ;
}
return shinfo . szTypeName ;
}
2009-06-27 19:42:17 +04:00
2009-06-28 00:43:42 +04:00
public static IntPtr getIcon ( string path , bool getLargeIcon )
{
SHFILEINFO shinfo = new SHFILEINFO ( ) ;
if ( 0 = = SHGetFileInfo ( path , 0 , ref shinfo , ( uint ) Marshal . SizeOf ( shinfo ) , SHGFI_ICON | ( getLargeIcon ? 0 : SHGFI_SMALLICON ) ) . ToInt32 ( ) )
{
return IntPtr . Zero ;
}
return shinfo . hIcon ;
}
2009-06-27 19:42:17 +04:00
public static int getAttribute ( string path )
{
SHFILEINFO shinfo = new SHFILEINFO ( ) ;
if ( 0 = = SHGetFileInfo ( path , 0 , ref shinfo , ( uint ) Marshal . SizeOf ( shinfo ) , SHGFI_ATTRIBUTES ) . ToInt32 ( ) )
{
return 0 ;
}
return ( int ) shinfo . dwAttributes ;
}
public static string getLinkLocation ( string path )
{
using ( ShellLink link = new ShellLink ( ) )
{
link . Load ( path ) ;
return link . GetPath ( ) ;
}
}
public static IntPtr getFileChooserBitmapHandle ( )
{
// Code copied from ShellFolder2.cpp Java_sun_awt_shell_Win32ShellFolder2_getFileChooserBitmapBits
IntPtr libShell32 = LoadLibrary ( "shell32.dll" ) ;
// Get a handle to an icon.
bool isVista = Environment . OSVersion . Version . Major > = 6 ;
IntPtr hBitmap = isVista ?
LoadImageName ( libShell32 , "IDB_TB_SH_DEF_16" , IMAGE_BITMAP , 0 , 0 , 0 ) :
LoadImageID ( libShell32 , 216 , IMAGE_BITMAP , 0 , 0 , 0 ) ;
if ( hBitmap . ToInt32 ( ) ! = 0 )
{
return hBitmap ;
}
IntPtr libComCtl32 = LoadLibrary ( "comctl32.dll" ) ;
return LoadImageID ( libComCtl32 , 124 , IMAGE_BITMAP , 0 , 0 , 0 ) ;
}
public static IntPtr getIconResource ( String libName , int iconID , int cxDesired , int cyDesired )
{
IntPtr hLibName = LoadLibrary ( libName ) ;
return LoadImageID ( hLibName , iconID , IMAGE_ICON , cxDesired , cyDesired , 0 ) ;
}
}
class ShellLink : IDisposable
{
[ComImport]
[Guid("0000010B-0000-0000-C000-000000000046")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IPersistFile
{
[PreserveSig]
void GetClassID ( out Guid pClassID ) ;
[PreserveSig]
void IsDirty ( ) ;
[PreserveSig]
void Load ( [ MarshalAs ( UnmanagedType . LPWStr ) ] string pszFileName , uint dwMode ) ;
[PreserveSig]
void Save ( [ MarshalAs ( UnmanagedType . LPWStr ) ] string pszFileName , [ MarshalAs ( UnmanagedType . Bool ) ] bool fRemember ) ;
[PreserveSig]
void SaveCompleted ( [ MarshalAs ( UnmanagedType . LPWStr ) ] string pszFileName ) ;
[PreserveSig]
void GetCurFile ( [ MarshalAs ( UnmanagedType . LPWStr ) ] out string ppszFileName ) ;
}
[ComImport]
[Guid("000214F9-0000-0000-C000-000000000046")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IShellLinkW
{
void GetPath ( [ Out , MarshalAs ( UnmanagedType . LPWStr ) ] StringBuilder pszFile , int cchMaxPath , IntPtr pfd , uint fFlags ) ;
void GetIDList ( out IntPtr ppidl ) ;
void SetIDList ( IntPtr pidl ) ;
void GetDescription ( [ Out , MarshalAs ( UnmanagedType . LPWStr ) ] StringBuilder pszFile , int cchMaxName ) ;
void SetDescription ( [ MarshalAs ( UnmanagedType . LPWStr ) ] string pszName ) ;
void GetWorkingDirectory ( [ Out , MarshalAs ( UnmanagedType . LPWStr ) ] StringBuilder pszDir , int cchMaxPath ) ;
void SetWorkingDirectory ( [ MarshalAs ( UnmanagedType . LPWStr ) ] string pszDir ) ;
void GetArguments ( [ Out , MarshalAs ( UnmanagedType . LPWStr ) ] StringBuilder pszArgs , int cchMaxPath ) ;
void SetArguments ( [ MarshalAs ( UnmanagedType . LPWStr ) ] string pszArgs ) ;
void GetHotkey ( out short pwHotkey ) ;
void SetHotkey ( short pwHotkey ) ;
void GetShowCmd ( out uint piShowCmd ) ;
void SetShowCmd ( uint piShowCmd ) ;
void GetIconLocation ( [ Out , MarshalAs ( UnmanagedType . LPWStr ) ] StringBuilder pszIconPath , int cchIconPath , out int piIcon ) ;
void SetIconLocation ( [ MarshalAs ( UnmanagedType . LPWStr ) ] string pszIconPath , int iIcon ) ;
void SetRelativePath ( [ MarshalAs ( UnmanagedType . LPWStr ) ] string pszPathRel , uint dwReserved ) ;
void Resolve ( IntPtr hWnd , uint fFlags ) ;
void SetPath ( [ MarshalAs ( UnmanagedType . LPWStr ) ] string pszFile ) ;
}
[Guid("00021401-0000-0000-C000-000000000046")]
[ClassInterfaceAttribute(ClassInterfaceType.None)]
[ComImport]
private class CShellLink { }
[Flags]
public enum EShowWindowFlags : uint
{
SW_HIDE = 0 ,
SW_SHOWNORMAL = 1 ,
SW_NORMAL = 1 ,
SW_SHOWMINIMIZED = 2 ,
SW_SHOWMAXIMIZED = 3 ,
SW_MAXIMIZE = 3 ,
SW_SHOWNOACTIVATE = 4 ,
SW_SHOW = 5 ,
SW_MINIMIZE = 6 ,
SW_SHOWMINNOACTIVE = 7 ,
SW_SHOWNA = 8 ,
SW_RESTORE = 9 ,
SW_SHOWDEFAULT = 10 ,
SW_MAX = 10
}
private IShellLinkW linkW = ( IShellLinkW ) new CShellLink ( ) ;
public void Dispose ( )
{
if ( linkW ! = null )
{
Marshal . ReleaseComObject ( linkW ) ;
linkW = null ;
}
}
public void SetPath ( string path )
{
linkW . SetPath ( path ) ;
}
public void SetDescription ( string description )
{
linkW . SetDescription ( description ) ;
}
public void SetWorkingDirectory ( string dir )
{
linkW . SetWorkingDirectory ( dir ) ;
}
public void SetArguments ( string args )
{
linkW . SetArguments ( args ) ;
}
public void SetShowCmd ( EShowWindowFlags cmd )
{
linkW . SetShowCmd ( ( uint ) cmd ) ;
}
public void Save ( string linkFile )
{
( ( IPersistFile ) linkW ) . Save ( linkFile , true ) ;
}
public void Load ( string linkFile )
{
( ( IPersistFile ) linkW ) . Load ( linkFile , 0 ) ;
}
public string GetArguments ( )
{
StringBuilder sb = new StringBuilder ( 512 ) ;
linkW . GetArguments ( sb , sb . Capacity ) ;
return sb . ToString ( ) ;
}
public string GetPath ( )
{
StringBuilder sb = new StringBuilder ( 512 ) ;
linkW . GetPath ( sb , sb . Capacity , IntPtr . Zero , 0 ) ;
return sb . ToString ( ) ;
}
2009-06-06 16:32:47 +04:00
}
}
2007-07-31 10:14:32 +04:00
namespace IKVM.NativeCode.sun.java2d
{
2007-12-18 14:05:30 +03:00
static class DefaultDisposerRecord
2007-07-31 10:14:32 +04:00
{
public static void invokeNativeDispose ( long disposerMethodPointer , long dataPointer )
{
throw new NotImplementedException ( ) ;
}
}
2007-12-18 14:05:30 +03:00
static class Disposer
2007-07-31 10:14:32 +04:00
{
public static void initIDs ( )
{
}
}
}
2009-05-03 22:44:22 +04:00
namespace IKVM.NativeCode.sun.java2d.pipe
{
static class Region
{
public static void initIDs ( ) { }
}
static class RenderBuffer
{
public static void copyFromArray ( object srcArray , long srcPos , long dstAddr , long length ) {
throw new NotImplementedException ( ) ;
}
}
}
2007-05-28 14:15:23 +04:00
namespace IKVM.NativeCode.sun.misc
{
2007-12-18 14:05:30 +03:00
static class GC
2007-06-22 13:51:42 +04:00
{
public static long maxObjectInspectionAge ( )
{
return 0 ;
}
}
2007-12-18 14:05:30 +03:00
static class MessageUtils
2007-06-11 13:17:29 +04:00
{
public static void toStderr ( string msg )
{
Console . Error . Write ( msg ) ;
}
public static void toStdout ( string msg )
{
Console . Out . Write ( msg ) ;
}
}
2007-12-18 14:05:30 +03:00
static class MiscHelper
2007-06-12 16:54:20 +04:00
{
2007-10-25 20:49:30 +04:00
public static object getAssemblyClassLoader ( Assembly asm , object extcl )
2007-06-12 16:54:20 +04:00
{
2007-10-25 20:49:30 +04:00
if ( extcl = = null | | asm . IsDefined ( typeof ( IKVM . Attributes . CustomAssemblyClassLoaderAttribute ) , false ) )
{
return ClassLoaderWrapper . GetAssemblyClassLoader ( asm ) . GetJavaClassLoader ( ) ;
}
return null ;
2007-06-12 16:54:20 +04:00
}
}
2007-12-18 14:05:30 +03:00
static class Signal
2007-06-09 12:33:09 +04:00
{
public static int findSignal ( string sigName )
{
return 0 ;
}
public static long handle0 ( int sig , long nativeH )
{
return 0 ;
}
public static void raise0 ( int sig )
{
throw new NotImplementedException ( ) ;
}
}
2007-12-18 14:05:30 +03:00
static class NativeSignalHandler
2007-06-09 12:33:09 +04:00
{
public static void handle0 ( int number , long handler )
{
throw new NotImplementedException ( ) ;
}
}
2007-12-18 14:05:30 +03:00
static class Perf
2007-07-12 12:40:32 +04:00
{
public static object attach ( object thisPerf , string user , int lvmid , int mode )
{
throw new NotImplementedException ( ) ;
}
public static void detach ( object thisPerf , object bb )
{
throw new NotImplementedException ( ) ;
}
public static object createLong ( object thisPerf , string name , int variability , int units , long value )
{
throw new NotImplementedException ( ) ;
}
public static object createByteArray ( object thisPerf , string name , int variability , int units , byte [ ] value , int maxLength )
{
throw new NotImplementedException ( ) ;
}
public static long highResCounter ( object thisPerf )
{
throw new NotImplementedException ( ) ;
}
public static long highResFrequency ( object thisPerf )
{
throw new NotImplementedException ( ) ;
}
public static void registerNatives ( )
{
}
}
2007-12-18 14:05:30 +03:00
static class Unsafe
2007-06-13 15:46:24 +04:00
{
public static void throwException ( object thisUnsafe , Exception x )
{
throw x ;
}
public static void ensureClassInitialized ( object thisUnsafe , object clazz )
{
TypeWrapper tw = TypeWrapper . FromClass ( clazz ) ;
if ( ! tw . IsArray )
{
tw . Finish ( ) ;
tw . RunClassInit ( ) ;
}
}
public static object allocateInstance ( object thisUnsafe , object clazz )
{
TypeWrapper wrapper = TypeWrapper . FromClass ( clazz ) ;
try
{
wrapper . Finish ( ) ;
}
catch ( RetargetableJavaException x )
{
throw x . ToJava ( ) ;
}
return FormatterServices . GetUninitializedObject ( wrapper . TypeAsBaseType ) ;
}
}
2007-12-18 14:05:30 +03:00
static class Version
2007-06-09 12:33:09 +04:00
{
public static string getJvmSpecialVersion ( )
{
throw new NotImplementedException ( ) ;
}
public static string getJdkSpecialVersion ( )
{
throw new NotImplementedException ( ) ;
}
public static bool getJvmVersionInfo ( )
{
throw new NotImplementedException ( ) ;
}
public static void getJdkVersionInfo ( )
{
throw new NotImplementedException ( ) ;
}
}
2007-12-18 14:05:30 +03:00
static class VM
2007-05-28 14:15:23 +04:00
{
public static void getThreadStateValues ( int [ ] [ ] vmThreadStateValues , string [ ] [ ] vmThreadStateNames )
{
// TODO
}
public static void initialize ( )
{
}
}
2007-07-12 12:40:32 +04:00
2007-12-18 14:05:30 +03:00
static class VMSupport
2007-07-12 12:40:32 +04:00
{
public static object initAgentProperties ( object props )
{
return props ;
}
}
}
namespace IKVM.NativeCode.sun.net.spi
{
2007-12-18 14:05:30 +03:00
static class DefaultProxySelector
2007-07-12 12:40:32 +04:00
{
public static bool init ( )
{
return true ;
}
public static object getSystemProxy ( object thisDefaultProxySelector , string protocol , string host )
{
// TODO on Whidbey we might be able to use System.Net.Configuration.DefaultProxySection.Proxy
return null ;
}
}
2007-05-28 14:15:23 +04:00
}
namespace IKVM.NativeCode.sun.reflect
{
2009-06-02 10:26:42 +04:00
#if ! FIRST_PASS
public interface IReflectionException
{
jlIllegalArgumentException GetIllegalArgumentException ( object obj ) ;
jlIllegalArgumentException SetIllegalArgumentException ( object obj ) ;
}
#endif
2007-12-18 14:05:30 +03:00
static class Reflection
2007-05-28 14:15:23 +04:00
{
2009-06-02 11:38:21 +04:00
#if CLASSGC
private sealed class State { internal int Value ; }
private static readonly ConditionalWeakTable < MethodBase , State > isHideFromJavaCache = new ConditionalWeakTable < MethodBase , State > ( ) ;
internal static bool IsHideFromJava ( MethodBase mb )
{
State state = isHideFromJavaCache . GetOrCreateValue ( mb ) ;
if ( state . Value = = 0 )
{
state . Value = IsHideFromJavaImpl ( mb ) ;
}
return state . Value = = 1 ;
}
private static int IsHideFromJavaImpl ( MethodBase mb )
{
if ( mb . Name . StartsWith ( "__<" , StringComparison . Ordinal ) )
{
return 1 ;
}
if ( mb . IsDefined ( typeof ( IKVM . Attributes . HideFromJavaAttribute ) , false ) | | mb . IsDefined ( typeof ( IKVM . Attributes . HideFromReflectionAttribute ) , false ) )
{
return 1 ;
}
return 2 ;
}
#else
2007-11-26 14:01:29 +03:00
private static readonly Dictionary < RuntimeMethodHandle , bool > isHideFromJavaCache = new Dictionary < RuntimeMethodHandle , bool > ( ) ;
2007-08-07 11:44:42 +04:00
internal static bool IsHideFromJava ( MethodBase mb )
{
2007-11-26 18:19:08 +03:00
if ( mb . Name . StartsWith ( "__<" , StringComparison . Ordinal ) )
{
return true ;
}
2007-11-26 14:01:29 +03:00
RuntimeMethodHandle handle ;
try
{
handle = mb . MethodHandle ;
}
catch ( InvalidOperationException )
{
// DynamicMethods don't have a RuntimeMethodHandle and we always want to hide them anyway
return true ;
}
catch ( NotSupportedException )
{
// DynamicMethods don't have a RuntimeMethodHandle and we always want to hide them anyway
return true ;
}
lock ( isHideFromJavaCache )
{
bool cached ;
if ( isHideFromJavaCache . TryGetValue ( handle , out cached ) )
{
return cached ;
}
}
bool isHide = mb . IsDefined ( typeof ( IKVM . Attributes . HideFromJavaAttribute ) , false ) | | mb . IsDefined ( typeof ( IKVM . Attributes . HideFromReflectionAttribute ) , false ) ;
lock ( isHideFromJavaCache )
2007-08-07 11:44:42 +04:00
{
2007-11-26 14:01:29 +03:00
isHideFromJavaCache [ handle ] = isHide ;
2007-08-07 11:44:42 +04:00
}
2007-11-26 14:01:29 +03:00
return isHide ;
2007-08-07 11:44:42 +04:00
}
2009-06-02 11:38:21 +04:00
#endif
2007-08-07 11:44:42 +04:00
2007-06-11 13:17:29 +04:00
// NOTE this method is hooked up explicitly through map.xml to prevent inlining of the native stub
// and tail-call optimization in the native stub.
2007-05-28 14:15:23 +04:00
public static object getCallerClass ( int realFramesToSkip )
{
2007-05-29 20:27:08 +04:00
#if FIRST_PASS
return null ;
#else
2007-06-11 13:17:29 +04:00
int i = 3 ;
if ( realFramesToSkip < = 1 )
2007-05-28 14:15:23 +04:00
{
2007-06-11 13:17:29 +04:00
i = 1 ;
realFramesToSkip = Math . Max ( realFramesToSkip + 2 , 2 ) ;
2007-05-28 14:15:23 +04:00
}
2007-06-11 13:17:29 +04:00
realFramesToSkip - - ;
2007-06-01 15:50:46 +04:00
for ( ; ; )
2007-05-29 20:27:08 +04:00
{
2007-06-11 13:17:29 +04:00
MethodBase method = new StackFrame ( i + + , false ) . GetMethod ( ) ;
if ( method = = null )
{
return null ;
}
Type type = method . DeclaringType ;
// NOTE these checks should be the same as the ones in SecurityManager.getClassContext
2007-08-07 11:44:42 +04:00
if ( IsHideFromJava ( method )
2007-06-11 13:17:29 +04:00
| | type = = null
2007-06-01 15:50:46 +04:00
| | type . Assembly = = typeof ( object ) . Assembly
2007-06-01 16:47:51 +04:00
| | type . Assembly = = typeof ( Reflection ) . Assembly
2007-12-27 18:16:49 +03:00
| | type . Assembly = = java . lang . SecurityManager . jniAssembly
2007-06-01 15:50:46 +04:00
| | type = = typeof ( jlrMethod )
2007-06-01 16:47:51 +04:00
| | type = = typeof ( jlrConstructor ) )
2007-05-29 20:27:08 +04:00
{
2007-06-01 15:50:46 +04:00
continue ;
2007-05-29 20:27:08 +04:00
}
2007-06-11 13:17:29 +04:00
if ( - - realFramesToSkip = = 0 )
{
return ClassLoaderWrapper . GetWrapperFromType ( type ) . ClassObject ;
}
2007-05-29 20:27:08 +04:00
}
#endif
2007-05-28 14:15:23 +04:00
}
public static int getClassAccessFlags ( object clazz )
{
return ( int ) TypeWrapper . FromClass ( clazz ) . Modifiers ;
}
public static bool checkInternalAccess ( object currentClass , object memberClass )
{
TypeWrapper current = TypeWrapper . FromClass ( currentClass ) ;
TypeWrapper member = TypeWrapper . FromClass ( memberClass ) ;
2009-02-10 10:24:30 +03:00
return member . IsInternal & & member . InternalsVisibleTo ( current ) ;
2007-05-28 14:15:23 +04:00
}
}
2007-12-18 14:05:30 +03:00
static class ReflectionFactory
2007-05-28 14:15:23 +04:00
{
2007-05-29 20:27:08 +04:00
#if ! FIRST_PASS
private static object [ ] ConvertArgs ( TypeWrapper [ ] argumentTypes , object [ ] args )
2007-05-28 14:15:23 +04:00
{
2007-05-29 20:27:08 +04:00
object [ ] nargs = new object [ args = = null ? 0 : args . Length ] ;
2007-06-01 15:50:46 +04:00
if ( nargs . Length ! = argumentTypes . Length )
{
throw new jlIllegalArgumentException ( "wrong number of arguments" ) ;
}
2007-05-29 20:27:08 +04:00
for ( int i = 0 ; i < nargs . Length ; i + + )
{
if ( argumentTypes [ i ] . IsPrimitive )
{
if ( args [ i ] = = null )
{
throw new jlIllegalArgumentException ( "primitive wrapper null" ) ;
}
2007-12-19 14:28:09 +03:00
nargs [ i ] = JVM . Unbox ( args [ i ] ) ;
2007-05-29 20:27:08 +04:00
// 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 ( nargs [ i ] is byte & & argumentTypes [ i ] ! = PrimitiveTypeWrapper . BYTE )
{
nargs [ i ] = ( sbyte ) ( byte ) nargs [ i ] ;
}
}
else
{
2007-09-25 10:12:59 +04:00
if ( args [ i ] ! = null & & ! argumentTypes [ i ] . IsInstance ( args [ i ] ) )
{
throw new jlIllegalArgumentException ( ) ;
}
2007-05-29 20:27:08 +04:00
nargs [ i ] = args [ i ] ;
}
}
return nargs ;
2007-05-28 14:15:23 +04:00
}
2007-05-29 20:27:08 +04:00
private sealed class MethodAccessorImpl : srMethodAccessor
{
private readonly MethodWrapper mw ;
internal MethodAccessorImpl ( jlrMethod method )
{
mw = MethodWrapper . FromMethodOrConstructor ( method ) ;
}
[IKVM.Attributes.HideFromJava]
2008-05-31 19:20:29 +04:00
public object invoke ( object obj , object [ ] args , global :: ikvm . @internal . CallerID callerID )
2007-05-29 20:27:08 +04:00
{
2007-06-01 15:50:46 +04:00
if ( ! mw . IsStatic & & ! mw . DeclaringType . IsInstance ( obj ) )
{
if ( obj = = null )
{
throw new jlNullPointerException ( ) ;
}
throw new jlIllegalArgumentException ( "object is not an instance of declaring class" ) ;
}
2007-05-29 20:27:08 +04:00
args = ConvertArgs ( mw . GetParameters ( ) , args ) ;
2007-06-01 15:50:46 +04:00
// if the method is an interface method, we must explicitly run <clinit>,
// because .NET reflection doesn't
if ( mw . DeclaringType . IsInterface )
{
mw . DeclaringType . RunClassInit ( ) ;
}
2007-05-29 20:27:08 +04:00
object retval ;
try
{
2008-08-25 08:16:59 +04:00
retval = ( ( ICustomInvoke ) mw ) . Invoke ( obj , args , callerID ) ;
2007-05-29 20:27:08 +04:00
}
catch ( MethodAccessException x )
{
// this can happen if we're calling a non-public method and the call stack doesn't have ReflectionPermission.MemberAccess
throw new jlIllegalAccessException ( ) . initCause ( x ) ;
}
if ( mw . ReturnType . IsPrimitive & & mw . ReturnType ! = PrimitiveTypeWrapper . VOID )
{
2007-12-19 14:28:09 +03:00
retval = JVM . Box ( retval ) ;
2007-05-29 20:27:08 +04:00
}
return retval ;
}
}
2008-08-21 10:40:22 +04:00
internal sealed class FastMethodAccessorImpl : srMethodAccessor
2007-05-29 20:27:08 +04:00
{
2007-09-24 15:57:00 +04:00
private static readonly MethodInfo valueOfByte ;
private static readonly MethodInfo valueOfBoolean ;
private static readonly MethodInfo valueOfChar ;
private static readonly MethodInfo valueOfShort ;
private static readonly MethodInfo valueOfInt ;
private static readonly MethodInfo valueOfFloat ;
private static readonly MethodInfo valueOfLong ;
private static readonly MethodInfo valueOfDouble ;
private static readonly MethodInfo byteValue ;
private static readonly MethodInfo booleanValue ;
private static readonly MethodInfo charValue ;
private static readonly MethodInfo shortValue ;
private static readonly MethodInfo intValue ;
private static readonly MethodInfo floatValue ;
private static readonly MethodInfo longValue ;
private static readonly MethodInfo doubleValue ;
internal static readonly ConstructorInfo invocationTargetExceptionCtor ;
2008-05-31 19:20:29 +04:00
private delegate object Invoker ( object obj , object [ ] args , global :: ikvm . @internal . CallerID callerID ) ;
2007-09-25 16:27:21 +04:00
private Invoker invoker ;
2007-09-24 15:57:00 +04:00
static FastMethodAccessorImpl ( )
{
valueOfByte = typeof ( jlByte ) . GetMethod ( "valueOf" , new Type [ ] { typeof ( byte ) } ) ;
valueOfBoolean = typeof ( jlBoolean ) . GetMethod ( "valueOf" , new Type [ ] { typeof ( bool ) } ) ;
valueOfChar = typeof ( jlCharacter ) . GetMethod ( "valueOf" , new Type [ ] { typeof ( char ) } ) ;
valueOfShort = typeof ( jlShort ) . GetMethod ( "valueOf" , new Type [ ] { typeof ( short ) } ) ;
valueOfInt = typeof ( jlInteger ) . GetMethod ( "valueOf" , new Type [ ] { typeof ( int ) } ) ;
valueOfFloat = typeof ( jlFloat ) . GetMethod ( "valueOf" , new Type [ ] { typeof ( float ) } ) ;
valueOfLong = typeof ( jlLong ) . GetMethod ( "valueOf" , new Type [ ] { typeof ( long ) } ) ;
valueOfDouble = typeof ( jlDouble ) . GetMethod ( "valueOf" , new Type [ ] { typeof ( double ) } ) ;
byteValue = typeof ( jlByte ) . GetMethod ( "byteValue" , Type . EmptyTypes ) ;
booleanValue = typeof ( jlBoolean ) . GetMethod ( "booleanValue" , Type . EmptyTypes ) ;
charValue = typeof ( jlCharacter ) . GetMethod ( "charValue" , Type . EmptyTypes ) ;
shortValue = typeof ( jlShort ) . GetMethod ( "shortValue" , Type . EmptyTypes ) ;
intValue = typeof ( jlInteger ) . GetMethod ( "intValue" , Type . EmptyTypes ) ;
floatValue = typeof ( jlFloat ) . GetMethod ( "floatValue" , Type . EmptyTypes ) ;
longValue = typeof ( jlLong ) . GetMethod ( "longValue" , Type . EmptyTypes ) ;
doubleValue = typeof ( jlDouble ) . GetMethod ( "doubleValue" , Type . EmptyTypes ) ;
invocationTargetExceptionCtor = typeof ( jlrInvocationTargetException ) . GetConstructor ( new Type [ ] { typeof ( Exception ) } ) ;
}
2008-09-25 09:17:21 +04:00
private sealed class RunClassInit
{
private FastMethodAccessorImpl outer ;
private TypeWrapper tw ;
private Invoker invoker ;
internal RunClassInit ( FastMethodAccessorImpl outer , TypeWrapper tw , Invoker invoker )
{
this . outer = outer ;
this . tw = tw ;
this . invoker = invoker ;
}
[IKVM.Attributes.HideFromJava]
internal object invoke ( object obj , object [ ] args , global :: ikvm . @internal . CallerID callerID )
{
// FXBUG pre-SP1 a DynamicMethod that calls a static method doesn't trigger the cctor, so we do that explicitly.
// even on .NET 2.0 SP2, interface method invocations don't run the interface cctor
// NOTE when testing, please test both the x86 and x64 CLR JIT, because they have different bugs (even on .NET 2.0 SP2)
tw . RunClassInit ( ) ;
outer . invoker = invoker ;
return invoker ( obj , args , callerID ) ;
}
}
2008-08-21 10:40:22 +04:00
internal FastMethodAccessorImpl ( jlrMethod method , bool nonvirtual )
2007-09-24 15:57:00 +04:00
{
MethodWrapper mw = MethodWrapper . FromMethodOrConstructor ( method ) ;
mw . DeclaringType . Finish ( ) ;
mw . ResolveMethod ( ) ;
2008-09-01 08:01:36 +04:00
DynamicMethod dm = DynamicMethodUtils . Create ( "__<Invoker>" , mw . DeclaringType . TypeAsBaseType , ! mw . IsPublic | | ! mw . DeclaringType . IsPublic | | nonvirtual , typeof ( object ) , new Type [ ] { typeof ( object ) , typeof ( object [ ] ) , typeof ( global :: ikvm . @internal . CallerID ) } ) ;
2008-06-03 16:10:07 +04:00
CodeEmitter ilgen = CodeEmitter . Create ( dm ) ;
2007-09-24 15:57:00 +04:00
LocalBuilder ret = ilgen . DeclareLocal ( typeof ( object ) ) ;
if ( ! mw . IsStatic )
{
// check target for null
ilgen . Emit ( OpCodes . Ldarg_0 ) ;
EmitHelper . NullCheck ( ilgen ) ;
}
2007-05-29 20:27:08 +04:00
2007-09-24 15:57:00 +04:00
// check args length
2008-06-03 16:10:07 +04:00
CodeEmitterLabel argsLengthOK = ilgen . DefineLabel ( ) ;
2007-09-24 15:57:00 +04:00
if ( mw . GetParameters ( ) . Length = = 0 )
{
// zero length array may be null
ilgen . Emit ( OpCodes . Ldarg_1 ) ;
ilgen . Emit ( OpCodes . Brfalse_S , argsLengthOK ) ;
}
ilgen . Emit ( OpCodes . Ldarg_1 ) ;
ilgen . Emit ( OpCodes . Ldlen ) ;
ilgen . Emit ( OpCodes . Ldc_I4 , mw . GetParameters ( ) . Length ) ;
ilgen . Emit ( OpCodes . Beq_S , argsLengthOK ) ;
EmitHelper . Throw ( ilgen , "java.lang.IllegalArgumentException" ) ;
ilgen . MarkLabel ( argsLengthOK ) ;
2007-05-29 20:27:08 +04:00
2007-09-24 15:57:00 +04:00
int thisCount = mw . IsStatic ? 0 : 1 ;
LocalBuilder [ ] args = new LocalBuilder [ mw . GetParameters ( ) . Length + thisCount ] ;
if ( ! mw . IsStatic )
2007-05-29 20:27:08 +04:00
{
2007-09-24 15:57:00 +04:00
args [ 0 ] = ilgen . DeclareLocal ( mw . DeclaringType . TypeAsSignatureType ) ;
2007-05-29 20:27:08 +04:00
}
2007-09-24 15:57:00 +04:00
for ( int i = thisCount ; i < args . Length ; i + + )
2007-05-29 20:27:08 +04:00
{
2007-09-24 15:57:00 +04:00
mw . GetParameters ( ) [ i - thisCount ] . Finish ( ) ;
args [ i ] = ilgen . DeclareLocal ( mw . GetParameters ( ) [ i - thisCount ] . TypeAsSignatureType ) ;
2007-05-29 20:27:08 +04:00
}
2007-09-24 15:57:00 +04:00
ilgen . BeginExceptionBlock ( ) ;
if ( ! mw . IsStatic )
{
ilgen . Emit ( OpCodes . Ldarg_0 ) ;
mw . DeclaringType . EmitCheckcast ( null , ilgen ) ;
mw . DeclaringType . EmitConvStackTypeToSignatureType ( ilgen , null ) ;
ilgen . Emit ( OpCodes . Stloc , args [ 0 ] ) ;
}
for ( int i = thisCount ; i < args . Length ; i + + )
{
ilgen . Emit ( OpCodes . Ldarg_1 ) ;
ilgen . Emit ( OpCodes . Ldc_I4 , i - thisCount ) ;
ilgen . Emit ( OpCodes . Ldelem_Ref ) ;
TypeWrapper tw = mw . GetParameters ( ) [ i - thisCount ] ;
EmitUnboxArg ( ilgen , tw ) ;
tw . EmitConvStackTypeToSignatureType ( ilgen , null ) ;
ilgen . Emit ( OpCodes . Stloc , args [ i ] ) ;
}
ilgen . BeginCatchBlock ( typeof ( InvalidCastException ) ) ;
EmitHelper . Throw ( ilgen , "java.lang.IllegalArgumentException" ) ;
ilgen . BeginCatchBlock ( typeof ( NullReferenceException ) ) ;
EmitHelper . Throw ( ilgen , "java.lang.IllegalArgumentException" ) ;
ilgen . EndExceptionBlock ( ) ;
2007-05-29 20:27:08 +04:00
2007-09-24 15:57:00 +04:00
// this is the actual call
ilgen . BeginExceptionBlock ( ) ;
for ( int i = 0 ; i < args . Length ; i + + )
2007-06-19 10:09:13 +04:00
{
2007-09-24 15:57:00 +04:00
if ( i = = 0 & & ! mw . IsStatic & & ( mw . DeclaringType . IsNonPrimitiveValueType | | mw . DeclaringType . IsGhost ) )
{
ilgen . Emit ( OpCodes . Ldloca , args [ i ] ) ;
}
else
{
ilgen . Emit ( OpCodes . Ldloc , args [ i ] ) ;
}
2007-06-19 10:09:13 +04:00
}
2008-05-31 19:20:29 +04:00
if ( mw . HasCallerID )
{
ilgen . Emit ( OpCodes . Ldarg_2 ) ;
}
2008-08-21 10:40:22 +04:00
if ( mw . IsStatic | | nonvirtual )
2007-06-19 10:09:13 +04:00
{
2007-09-24 15:57:00 +04:00
mw . EmitCall ( ilgen ) ;
}
else
{
2008-08-25 08:16:59 +04:00
mw . EmitCallvirtReflect ( ilgen ) ;
2007-06-19 10:09:13 +04:00
}
2007-09-24 15:57:00 +04:00
mw . ReturnType . EmitConvSignatureTypeToStackType ( ilgen ) ;
BoxReturnValue ( ilgen , mw . ReturnType ) ;
ilgen . Emit ( OpCodes . Stloc , ret ) ;
ilgen . BeginCatchBlock ( typeof ( Exception ) ) ;
ilgen . Emit ( OpCodes . Ldc_I4_1 ) ;
ilgen . Emit ( OpCodes . Call , Compiler . mapExceptionFastMethod ) ;
ilgen . Emit ( OpCodes . Newobj , invocationTargetExceptionCtor ) ;
ilgen . Emit ( OpCodes . Throw ) ;
ilgen . EndExceptionBlock ( ) ;
ilgen . Emit ( OpCodes . Ldloc , ret ) ;
ilgen . Emit ( OpCodes . Ret ) ;
invoker = ( Invoker ) dm . CreateDelegate ( typeof ( Invoker ) ) ;
2008-09-25 09:17:21 +04:00
if ( ( mw . IsStatic | | mw . DeclaringType . IsInterface ) & & mw . DeclaringType . HasStaticInitializer )
{
invoker = new Invoker ( new RunClassInit ( this , mw . DeclaringType , invoker ) . invoke ) ;
}
2007-06-19 10:09:13 +04:00
}
2008-06-03 16:10:07 +04:00
private static void Expand ( CodeEmitter ilgen , TypeWrapper type )
2007-06-19 10:09:13 +04:00
{
2007-09-24 15:57:00 +04:00
if ( type = = PrimitiveTypeWrapper . FLOAT )
2007-06-19 10:09:13 +04:00
{
2007-09-24 15:57:00 +04:00
ilgen . Emit ( OpCodes . Conv_R4 ) ;
2007-06-19 10:09:13 +04:00
}
2007-09-24 15:57:00 +04:00
else if ( type = = PrimitiveTypeWrapper . LONG )
2007-06-19 10:09:13 +04:00
{
2007-09-24 15:57:00 +04:00
ilgen . Emit ( OpCodes . Conv_I8 ) ;
2007-06-19 10:09:13 +04:00
}
2007-09-24 15:57:00 +04:00
else if ( type = = PrimitiveTypeWrapper . DOUBLE )
2007-06-19 10:09:13 +04:00
{
2007-09-24 15:57:00 +04:00
ilgen . Emit ( OpCodes . Conv_R8 ) ;
2007-06-19 10:09:13 +04:00
}
}
2007-05-29 20:27:08 +04:00
2008-06-03 16:10:07 +04:00
internal static void EmitUnboxArg ( CodeEmitter ilgen , TypeWrapper type )
2007-05-29 20:27:08 +04:00
{
2007-09-24 15:57:00 +04:00
if ( type = = PrimitiveTypeWrapper . BYTE )
{
ilgen . Emit ( OpCodes . Castclass , typeof ( jlByte ) ) ;
ilgen . Emit ( OpCodes . Call , byteValue ) ;
}
else if ( type = = PrimitiveTypeWrapper . BOOLEAN )
{
ilgen . Emit ( OpCodes . Castclass , typeof ( jlBoolean ) ) ;
ilgen . Emit ( OpCodes . Call , booleanValue ) ;
}
else if ( type = = PrimitiveTypeWrapper . CHAR )
{
ilgen . Emit ( OpCodes . Castclass , typeof ( jlCharacter ) ) ;
ilgen . Emit ( OpCodes . Call , charValue ) ;
}
else if ( type = = PrimitiveTypeWrapper . SHORT
| | type = = PrimitiveTypeWrapper . INT
| | type = = PrimitiveTypeWrapper . FLOAT
| | type = = PrimitiveTypeWrapper . LONG
| | type = = PrimitiveTypeWrapper . DOUBLE )
{
ilgen . Emit ( OpCodes . Dup ) ;
ilgen . Emit ( OpCodes . Isinst , typeof ( jlByte ) ) ;
2008-06-03 16:10:07 +04:00
CodeEmitterLabel next = ilgen . DefineLabel ( ) ;
2007-09-24 15:57:00 +04:00
ilgen . Emit ( OpCodes . Brfalse_S , next ) ;
ilgen . Emit ( OpCodes . Call , byteValue ) ;
ilgen . Emit ( OpCodes . Conv_I1 ) ;
Expand ( ilgen , type ) ;
2008-06-03 16:10:07 +04:00
CodeEmitterLabel done = ilgen . DefineLabel ( ) ;
2007-09-24 15:57:00 +04:00
ilgen . Emit ( OpCodes . Br_S , done ) ;
ilgen . MarkLabel ( next ) ;
if ( type = = PrimitiveTypeWrapper . SHORT )
{
ilgen . Emit ( OpCodes . Castclass , typeof ( jlShort ) ) ;
ilgen . Emit ( OpCodes . Call , shortValue ) ;
}
else
{
ilgen . Emit ( OpCodes . Dup ) ;
ilgen . Emit ( OpCodes . Isinst , typeof ( jlShort ) ) ;
next = ilgen . DefineLabel ( ) ;
ilgen . Emit ( OpCodes . Brfalse_S , next ) ;
ilgen . Emit ( OpCodes . Call , shortValue ) ;
Expand ( ilgen , type ) ;
ilgen . Emit ( OpCodes . Br_S , done ) ;
ilgen . MarkLabel ( next ) ;
ilgen . Emit ( OpCodes . Dup ) ;
ilgen . Emit ( OpCodes . Isinst , typeof ( jlCharacter ) ) ;
next = ilgen . DefineLabel ( ) ;
ilgen . Emit ( OpCodes . Brfalse_S , next ) ;
ilgen . Emit ( OpCodes . Call , charValue ) ;
Expand ( ilgen , type ) ;
ilgen . Emit ( OpCodes . Br_S , done ) ;
ilgen . MarkLabel ( next ) ;
if ( type = = PrimitiveTypeWrapper . INT )
{
ilgen . Emit ( OpCodes . Castclass , typeof ( jlInteger ) ) ;
ilgen . Emit ( OpCodes . Call , intValue ) ;
}
else
{
ilgen . Emit ( OpCodes . Dup ) ;
ilgen . Emit ( OpCodes . Isinst , typeof ( jlInteger ) ) ;
next = ilgen . DefineLabel ( ) ;
ilgen . Emit ( OpCodes . Brfalse_S , next ) ;
ilgen . Emit ( OpCodes . Call , intValue ) ;
Expand ( ilgen , type ) ;
ilgen . Emit ( OpCodes . Br_S , done ) ;
ilgen . MarkLabel ( next ) ;
if ( type = = PrimitiveTypeWrapper . LONG )
{
ilgen . Emit ( OpCodes . Castclass , typeof ( jlLong ) ) ;
ilgen . Emit ( OpCodes . Call , longValue ) ;
}
else
{
ilgen . Emit ( OpCodes . Dup ) ;
ilgen . Emit ( OpCodes . Isinst , typeof ( jlLong ) ) ;
next = ilgen . DefineLabel ( ) ;
ilgen . Emit ( OpCodes . Brfalse_S , next ) ;
ilgen . Emit ( OpCodes . Call , longValue ) ;
Expand ( ilgen , type ) ;
ilgen . Emit ( OpCodes . Br_S , done ) ;
ilgen . MarkLabel ( next ) ;
if ( type = = PrimitiveTypeWrapper . FLOAT )
{
ilgen . Emit ( OpCodes . Castclass , typeof ( jlFloat ) ) ;
ilgen . Emit ( OpCodes . Call , floatValue ) ;
}
else if ( type = = PrimitiveTypeWrapper . DOUBLE )
{
ilgen . Emit ( OpCodes . Dup ) ;
ilgen . Emit ( OpCodes . Isinst , typeof ( jlFloat ) ) ;
next = ilgen . DefineLabel ( ) ;
ilgen . Emit ( OpCodes . Brfalse_S , next ) ;
ilgen . Emit ( OpCodes . Call , floatValue ) ;
ilgen . Emit ( OpCodes . Br_S , done ) ;
ilgen . MarkLabel ( next ) ;
ilgen . Emit ( OpCodes . Castclass , typeof ( jlDouble ) ) ;
ilgen . Emit ( OpCodes . Call , doubleValue ) ;
}
else
{
throw new InvalidOperationException ( ) ;
}
}
}
}
ilgen . MarkLabel ( done ) ;
}
else
{
type . EmitCheckcast ( null , ilgen ) ;
}
}
2008-06-03 16:10:07 +04:00
private static void BoxReturnValue ( CodeEmitter ilgen , TypeWrapper type )
2007-09-24 15:57:00 +04:00
{
if ( type = = PrimitiveTypeWrapper . VOID )
{
ilgen . Emit ( OpCodes . Ldnull ) ;
}
else if ( type = = PrimitiveTypeWrapper . BYTE )
{
ilgen . Emit ( OpCodes . Call , valueOfByte ) ;
}
else if ( type = = PrimitiveTypeWrapper . BOOLEAN )
{
ilgen . Emit ( OpCodes . Call , valueOfBoolean ) ;
}
else if ( type = = PrimitiveTypeWrapper . CHAR )
{
ilgen . Emit ( OpCodes . Call , valueOfChar ) ;
}
else if ( type = = PrimitiveTypeWrapper . SHORT )
{
ilgen . Emit ( OpCodes . Call , valueOfShort ) ;
}
else if ( type = = PrimitiveTypeWrapper . INT )
{
ilgen . Emit ( OpCodes . Call , valueOfInt ) ;
}
else if ( type = = PrimitiveTypeWrapper . FLOAT )
{
ilgen . Emit ( OpCodes . Call , valueOfFloat ) ;
}
else if ( type = = PrimitiveTypeWrapper . LONG )
{
ilgen . Emit ( OpCodes . Call , valueOfLong ) ;
}
else if ( type = = PrimitiveTypeWrapper . DOUBLE )
{
ilgen . Emit ( OpCodes . Call , valueOfDouble ) ;
}
}
[IKVM.Attributes.HideFromJava]
2008-05-31 19:20:29 +04:00
public object invoke ( object obj , object [ ] args , global :: ikvm . @internal . CallerID callerID )
2007-09-24 15:57:00 +04:00
{
2008-05-31 19:20:29 +04:00
return invoker ( obj , args , callerID ) ;
2007-09-24 15:57:00 +04:00
}
}
private sealed class ConstructorAccessorImpl : srConstructorAccessor
{
private readonly MethodWrapper mw ;
internal ConstructorAccessorImpl ( jlrConstructor constructor )
{
mw = MethodWrapper . FromMethodOrConstructor ( constructor ) ;
}
[IKVM.Attributes.HideFromJava]
public object newInstance ( object [ ] args )
{
args = ConvertArgs ( mw . GetParameters ( ) , args ) ;
try
{
2008-08-25 08:16:59 +04:00
return ( ( ICustomInvoke ) mw ) . Invoke ( null , args , null ) ;
2007-09-24 15:57:00 +04:00
}
catch ( MethodAccessException x )
{
// this can happen if we're calling a non-public method and the call stack doesn't have ReflectionPermission.MemberAccess
throw new jlIllegalAccessException ( ) . initCause ( x ) ;
}
}
}
private sealed class FastConstructorAccessorImpl : srConstructorAccessor
{
private delegate object Invoker ( object [ ] args ) ;
private Invoker invoker ;
internal FastConstructorAccessorImpl ( jlrConstructor constructor )
{
MethodWrapper mw = MethodWrapper . FromMethodOrConstructor ( constructor ) ;
mw . DeclaringType . Finish ( ) ;
mw . ResolveMethod ( ) ;
2008-09-01 08:01:36 +04:00
DynamicMethod dm = DynamicMethodUtils . Create ( "__<Invoker>" , mw . DeclaringType . TypeAsTBD , ! mw . IsPublic | | ! mw . DeclaringType . IsPublic , typeof ( object ) , new Type [ ] { typeof ( object [ ] ) } ) ;
2008-06-03 16:10:07 +04:00
CodeEmitter ilgen = CodeEmitter . Create ( dm ) ;
2007-09-24 15:57:00 +04:00
LocalBuilder ret = ilgen . DeclareLocal ( typeof ( object ) ) ;
// check args length
2008-06-03 16:10:07 +04:00
CodeEmitterLabel argsLengthOK = ilgen . DefineLabel ( ) ;
2007-09-24 15:57:00 +04:00
if ( mw . GetParameters ( ) . Length = = 0 )
{
// zero length array may be null
2007-12-04 11:08:33 +03:00
ilgen . Emit ( OpCodes . Ldarg_0 ) ;
2007-09-24 15:57:00 +04:00
ilgen . Emit ( OpCodes . Brfalse_S , argsLengthOK ) ;
}
2007-12-04 11:08:33 +03:00
ilgen . Emit ( OpCodes . Ldarg_0 ) ;
2007-09-24 15:57:00 +04:00
ilgen . Emit ( OpCodes . Ldlen ) ;
ilgen . Emit ( OpCodes . Ldc_I4 , mw . GetParameters ( ) . Length ) ;
ilgen . Emit ( OpCodes . Beq_S , argsLengthOK ) ;
EmitHelper . Throw ( ilgen , "java.lang.IllegalArgumentException" ) ;
ilgen . MarkLabel ( argsLengthOK ) ;
LocalBuilder [ ] args = new LocalBuilder [ mw . GetParameters ( ) . Length ] ;
for ( int i = 0 ; i < args . Length ; i + + )
{
mw . GetParameters ( ) [ i ] . Finish ( ) ;
args [ i ] = ilgen . DeclareLocal ( mw . GetParameters ( ) [ i ] . TypeAsSignatureType ) ;
}
ilgen . BeginExceptionBlock ( ) ;
for ( int i = 0 ; i < args . Length ; i + + )
{
2007-12-04 11:08:33 +03:00
ilgen . Emit ( OpCodes . Ldarg_0 ) ;
2007-09-24 15:57:00 +04:00
ilgen . Emit ( OpCodes . Ldc_I4 , i ) ;
ilgen . Emit ( OpCodes . Ldelem_Ref ) ;
TypeWrapper tw = mw . GetParameters ( ) [ i ] ;
FastMethodAccessorImpl . EmitUnboxArg ( ilgen , tw ) ;
tw . EmitConvStackTypeToSignatureType ( ilgen , null ) ;
ilgen . Emit ( OpCodes . Stloc , args [ i ] ) ;
}
ilgen . BeginCatchBlock ( typeof ( InvalidCastException ) ) ;
EmitHelper . Throw ( ilgen , "java.lang.IllegalArgumentException" ) ;
ilgen . BeginCatchBlock ( typeof ( NullReferenceException ) ) ;
EmitHelper . Throw ( ilgen , "java.lang.IllegalArgumentException" ) ;
ilgen . EndExceptionBlock ( ) ;
// this is the actual call
ilgen . BeginExceptionBlock ( ) ;
for ( int i = 0 ; i < args . Length ; i + + )
{
ilgen . Emit ( OpCodes . Ldloc , args [ i ] ) ;
}
mw . EmitNewobj ( ilgen ) ;
ilgen . Emit ( OpCodes . Stloc , ret ) ;
ilgen . BeginCatchBlock ( typeof ( Exception ) ) ;
ilgen . Emit ( OpCodes . Ldc_I4_1 ) ;
ilgen . Emit ( OpCodes . Call , Compiler . mapExceptionFastMethod ) ;
ilgen . Emit ( OpCodes . Newobj , FastMethodAccessorImpl . invocationTargetExceptionCtor ) ;
ilgen . Emit ( OpCodes . Throw ) ;
ilgen . EndExceptionBlock ( ) ;
ilgen . Emit ( OpCodes . Ldloc , ret ) ;
ilgen . Emit ( OpCodes . Ret ) ;
invoker = ( Invoker ) dm . CreateDelegate ( typeof ( Invoker ) ) ;
}
[IKVM.Attributes.HideFromJava]
public object newInstance ( object [ ] args )
{
return invoker ( args ) ;
}
}
private sealed class FastSerializationConstructorAccessorImpl : srConstructorAccessor
{
private static readonly MethodInfo GetTypeFromHandleMethod = typeof ( Type ) . GetMethod ( "GetTypeFromHandle" , new Type [ ] { typeof ( RuntimeTypeHandle ) } ) ;
private static readonly MethodInfo GetUninitializedObjectMethod = typeof ( FormatterServices ) . GetMethod ( "GetUninitializedObject" , new Type [ ] { typeof ( Type ) } ) ;
private delegate object InvokeCtor ( ) ;
private InvokeCtor invoker ;
internal FastSerializationConstructorAccessorImpl ( jlrConstructor constructorToCall , jlClass classToInstantiate )
{
MethodWrapper constructor = MethodWrapper . FromMethodOrConstructor ( constructorToCall ) ;
2008-08-21 10:53:48 +04:00
if ( constructor . GetParameters ( ) . Length ! = 0 )
{
throw new NotImplementedException ( "Serialization constructor cannot have parameters" ) ;
}
2007-09-24 15:57:00 +04:00
constructor . Link ( ) ;
constructor . ResolveMethod ( ) ;
Type type ;
try
{
TypeWrapper wrapper = TypeWrapper . FromClass ( classToInstantiate ) ;
wrapper . Finish ( ) ;
type = wrapper . TypeAsBaseType ;
}
catch ( RetargetableJavaException x )
{
throw x . ToJava ( ) ;
}
2008-09-01 08:01:36 +04:00
DynamicMethod dm = DynamicMethodUtils . Create ( "__<SerializationCtor>" , constructor . DeclaringType . TypeAsBaseType , true , typeof ( object ) , null ) ;
2008-06-03 16:10:07 +04:00
CodeEmitter ilgen = CodeEmitter . Create ( dm ) ;
2007-09-24 15:57:00 +04:00
ilgen . Emit ( OpCodes . Ldtoken , type ) ;
ilgen . Emit ( OpCodes . Call , GetTypeFromHandleMethod ) ;
ilgen . Emit ( OpCodes . Call , GetUninitializedObjectMethod ) ;
ilgen . Emit ( OpCodes . Dup ) ;
constructor . EmitCall ( ilgen ) ;
ilgen . Emit ( OpCodes . Ret ) ;
invoker = ( InvokeCtor ) dm . CreateDelegate ( typeof ( InvokeCtor ) ) ;
}
[IKVM.Attributes.HideFromJava]
public object newInstance ( object [ ] args )
{
return invoker ( ) ;
}
}
2009-02-27 08:56:22 +03:00
sealed class ActivatorConstructorAccessor : srConstructorAccessor
{
private readonly Type type ;
internal ActivatorConstructorAccessor ( MethodWrapper mw )
{
this . type = mw . DeclaringType . TypeAsBaseType ;
}
public object newInstance ( object [ ] objarr )
{
return Activator . CreateInstance ( type ) ;
}
internal static bool IsSuitable ( MethodWrapper mw )
{
MethodBase mb = mw . GetMethod ( ) ;
return mb ! = null
& & mb . IsConstructor
& & mb . IsPublic
& & mb . DeclaringType . IsPublic
& & mb . DeclaringType = = mw . DeclaringType . TypeAsBaseType
& & mb . GetParameters ( ) . Length = = 0 ;
}
}
2009-06-02 10:26:42 +04:00
private abstract class FieldAccessorImplBase : srFieldAccessor , IReflectionException
2007-09-24 15:57:00 +04:00
{
2009-06-02 10:26:42 +04:00
private readonly jlrField field ;
2007-09-24 15:57:00 +04:00
protected readonly FieldWrapper fw ;
protected readonly bool isFinal ;
private bool runInit ;
private FieldAccessorImplBase ( jlrField field , bool overrideAccessCheck )
{
2009-06-02 10:26:42 +04:00
this . field = field ;
2007-09-24 15:57:00 +04:00
fw = FieldWrapper . FromField ( field ) ;
isFinal = ( ! overrideAccessCheck | | fw . IsStatic ) & & fw . IsFinal ;
2007-06-01 15:50:46 +04:00
runInit = fw . DeclaringType . IsInterface ;
}
2009-06-02 10:26:42 +04:00
private String GetQualifiedFieldName ( )
{
return field . getDeclaringClass ( ) . getName ( ) + "." + field . getName ( ) ;
}
public jlIllegalArgumentException GetIllegalArgumentException ( object obj )
{
// LAME like JDK 6 we return the wrong exception message (talking about setting the field, instead of getting)
return SetIllegalArgumentException ( obj ) ;
}
public jlIllegalArgumentException SetIllegalArgumentException ( object obj )
{
// LAME like JDK 6 we return the wrong exception message (when obj is the object, instead of the value)
return SetIllegalArgumentException ( obj ! = null ? irUtil . getClassFromObject ( obj ) . getName ( ) : "" , "" ) ;
}
private jlIllegalArgumentException SetIllegalArgumentException ( string attemptedType , string attemptedValue )
{
return new jlIllegalArgumentException ( GetSetMessage ( attemptedType , attemptedValue ) ) ;
}
protected jlIllegalAccessException FinalFieldIllegalAccessException ( object obj )
{
return FinalFieldIllegalAccessException ( obj ! = null ? irUtil . getClassFromObject ( obj ) . getName ( ) : "" , "" ) ;
}
private jlIllegalAccessException FinalFieldIllegalAccessException ( string attemptedType , string attemptedValue )
{
return new jlIllegalAccessException ( GetSetMessage ( attemptedType , attemptedValue ) ) ;
}
private jlIllegalArgumentException GetIllegalArgumentException ( string type )
{
return new jlIllegalArgumentException ( "Attempt to get " + field . getType ( ) . getName ( ) + " field \"" + GetQualifiedFieldName ( ) + "\" with illegal data type conversion to " + type ) ;
}
// this message comes from sun.reflect.UnsafeFieldAccessorImpl
private string GetSetMessage ( String attemptedType , String attemptedValue )
{
String err = "Can not set" ;
if ( jlrModifier . isStatic ( field . getModifiers ( ) ) )
err + = " static" ;
if ( isFinal )
err + = " final" ;
err + = " " + field . getType ( ) . getName ( ) + " field " + GetQualifiedFieldName ( ) + " to " ;
if ( attemptedValue . Length > 0 )
{
err + = "(" + attemptedType + ")" + attemptedValue ;
}
else
{
if ( attemptedType . Length > 0 )
err + = attemptedType ;
else
err + = "null value" ;
}
return err ;
}
2007-05-29 20:27:08 +04:00
public virtual bool getBoolean ( object obj )
{
2009-06-02 10:26:42 +04:00
throw GetIllegalArgumentException ( "boolean" ) ;
2007-05-29 20:27:08 +04:00
}
public virtual byte getByte ( object obj )
{
2009-06-02 10:26:42 +04:00
throw GetIllegalArgumentException ( "byte" ) ;
2007-05-29 20:27:08 +04:00
}
public virtual char getChar ( object obj )
{
2009-06-02 10:26:42 +04:00
throw GetIllegalArgumentException ( "char" ) ;
2007-05-29 20:27:08 +04:00
}
public virtual short getShort ( object obj )
{
2009-06-02 10:26:42 +04:00
throw GetIllegalArgumentException ( "short" ) ;
2007-05-29 20:27:08 +04:00
}
public virtual int getInt ( object obj )
{
2009-06-02 10:26:42 +04:00
throw GetIllegalArgumentException ( "int" ) ;
2007-05-29 20:27:08 +04:00
}
public virtual long getLong ( object obj )
{
2009-06-02 10:26:42 +04:00
throw GetIllegalArgumentException ( "long" ) ;
2007-05-29 20:27:08 +04:00
}
public virtual float getFloat ( object obj )
{
2009-06-02 10:26:42 +04:00
throw GetIllegalArgumentException ( "float" ) ;
2007-05-29 20:27:08 +04:00
}
public virtual double getDouble ( object obj )
{
2009-06-02 10:26:42 +04:00
throw GetIllegalArgumentException ( "double" ) ;
2007-05-29 20:27:08 +04:00
}
public virtual void setBoolean ( object obj , bool z )
{
2009-06-02 10:26:42 +04:00
throw SetIllegalArgumentException ( "boolean" , jlBoolean . toString ( z ) ) ;
2007-05-29 20:27:08 +04:00
}
public virtual void setByte ( object obj , byte b )
{
2009-06-02 10:26:42 +04:00
throw SetIllegalArgumentException ( "byte" , jlByte . toString ( b ) ) ;
2007-05-29 20:27:08 +04:00
}
public virtual void setChar ( object obj , char c )
{
2009-06-02 10:26:42 +04:00
throw SetIllegalArgumentException ( "char" , jlCharacter . toString ( c ) ) ;
2007-05-29 20:27:08 +04:00
}
public virtual void setShort ( object obj , short s )
{
2009-06-02 10:26:42 +04:00
throw SetIllegalArgumentException ( "short" , jlShort . toString ( s ) ) ;
2007-05-29 20:27:08 +04:00
}
public virtual void setInt ( object obj , int i )
{
2009-06-02 10:26:42 +04:00
throw SetIllegalArgumentException ( "int" , jlInteger . toString ( i ) ) ;
2007-05-29 20:27:08 +04:00
}
public virtual void setLong ( object obj , long l )
{
2009-06-02 10:26:42 +04:00
throw SetIllegalArgumentException ( "long" , jlLong . toString ( l ) ) ;
2007-05-29 20:27:08 +04:00
}
public virtual void setFloat ( object obj , float f )
{
2009-06-02 10:26:42 +04:00
throw SetIllegalArgumentException ( "float" , jlFloat . toString ( f ) ) ;
2007-05-29 20:27:08 +04:00
}
public virtual void setDouble ( object obj , double d )
{
2009-06-02 10:26:42 +04:00
throw SetIllegalArgumentException ( "double" , jlDouble . toString ( d ) ) ;
2007-05-29 20:27:08 +04:00
}
public abstract object get ( object obj ) ;
public abstract void set ( object obj , object value ) ;
2008-08-21 10:53:48 +04:00
private abstract class ObjectField : FieldAccessorImplBase
2007-05-29 20:27:08 +04:00
{
private readonly jlClass fieldType ;
internal ObjectField ( jlrField field , bool overrideAccessCheck )
: base ( field , overrideAccessCheck )
{
fieldType = field . getType ( ) ;
}
}
2007-09-24 15:57:00 +04:00
private class ByteField : FieldAccessorImplBase
2007-05-29 20:27:08 +04:00
{
internal ByteField ( jlrField field , bool overrideAccessCheck )
: base ( field , overrideAccessCheck )
{
}
2007-09-24 15:57:00 +04:00
public sealed override short getShort ( object obj )
2007-05-29 20:27:08 +04:00
{
return ( sbyte ) getByte ( obj ) ;
}
2007-09-24 15:57:00 +04:00
public sealed override int getInt ( object obj )
2007-05-29 20:27:08 +04:00
{
return ( sbyte ) getByte ( obj ) ;
}
2007-09-24 15:57:00 +04:00
public sealed override long getLong ( object obj )
2007-05-29 20:27:08 +04:00
{
return ( sbyte ) getByte ( obj ) ;
}
2007-09-24 15:57:00 +04:00
public sealed override float getFloat ( object obj )
2007-05-29 20:27:08 +04:00
{
return ( sbyte ) getByte ( obj ) ;
}
2007-09-24 15:57:00 +04:00
public sealed override double getDouble ( object obj )
2007-05-29 20:27:08 +04:00
{
return ( sbyte ) getByte ( obj ) ;
}
2007-09-24 15:57:00 +04:00
public sealed override object get ( object obj )
2007-05-29 20:27:08 +04:00
{
return jlByte . valueOf ( getByte ( obj ) ) ;
}
2007-09-24 15:57:00 +04:00
public sealed override void set ( object obj , object val )
2007-05-29 20:27:08 +04:00
{
if ( ! ( val is jlByte ) )
{
2009-06-02 10:26:42 +04:00
throw SetIllegalArgumentException ( val ) ;
2007-05-29 20:27:08 +04:00
}
setByte ( obj , ( ( jlByte ) val ) . byteValue ( ) ) ;
}
}
2007-09-24 15:57:00 +04:00
private class BooleanField : FieldAccessorImplBase
2007-05-29 20:27:08 +04:00
{
internal BooleanField ( jlrField field , bool overrideAccessCheck )
: base ( field , overrideAccessCheck )
{
}
2007-09-24 15:57:00 +04:00
public sealed override object get ( object obj )
2007-05-29 20:27:08 +04:00
{
return jlBoolean . valueOf ( getBoolean ( obj ) ) ;
}
2007-09-24 15:57:00 +04:00
public sealed override void set ( object obj , object val )
2007-05-29 20:27:08 +04:00
{
if ( ! ( val is jlBoolean ) )
{
2009-06-02 10:26:42 +04:00
throw SetIllegalArgumentException ( val ) ;
2007-05-29 20:27:08 +04:00
}
setBoolean ( obj , ( ( jlBoolean ) val ) . booleanValue ( ) ) ;
}
}
2007-09-24 15:57:00 +04:00
private class CharField : FieldAccessorImplBase
2007-05-29 20:27:08 +04:00
{
internal CharField ( jlrField field , bool overrideAccessCheck )
: base ( field , overrideAccessCheck )
{
}
2007-09-24 15:57:00 +04:00
public sealed override int getInt ( object obj )
2007-05-29 20:27:08 +04:00
{
return getChar ( obj ) ;
}
2007-09-24 15:57:00 +04:00
public sealed override long getLong ( object obj )
2007-05-29 20:27:08 +04:00
{
return getChar ( obj ) ;
}
2007-09-24 15:57:00 +04:00
public sealed override float getFloat ( object obj )
2007-05-29 20:27:08 +04:00
{
return getChar ( obj ) ;
}
2007-09-24 15:57:00 +04:00
public sealed override double getDouble ( object obj )
2007-05-29 20:27:08 +04:00
{
return getChar ( obj ) ;
}
2007-09-24 15:57:00 +04:00
public sealed override object get ( object obj )
2007-05-29 20:27:08 +04:00
{
return jlCharacter . valueOf ( getChar ( obj ) ) ;
}
2007-09-24 15:57:00 +04:00
public sealed override void set ( object obj , object val )
2007-05-29 20:27:08 +04:00
{
if ( val is jlCharacter )
setChar ( obj , ( ( jlCharacter ) val ) . charValue ( ) ) ;
else
2009-06-02 10:26:42 +04:00
throw SetIllegalArgumentException ( val ) ;
2007-05-29 20:27:08 +04:00
}
}
2007-09-24 15:57:00 +04:00
private class ShortField : FieldAccessorImplBase
2007-05-29 20:27:08 +04:00
{
internal ShortField ( jlrField field , bool overrideAccessCheck )
: base ( field , overrideAccessCheck )
{
}
2007-09-24 15:57:00 +04:00
public sealed override int getInt ( object obj )
2007-05-29 20:27:08 +04:00
{
return getShort ( obj ) ;
}
2007-09-24 15:57:00 +04:00
public sealed override long getLong ( object obj )
2007-05-29 20:27:08 +04:00
{
return getShort ( obj ) ;
}
2007-09-24 15:57:00 +04:00
public sealed override float getFloat ( object obj )
2007-05-29 20:27:08 +04:00
{
return getShort ( obj ) ;
}
2007-09-24 15:57:00 +04:00
public sealed override double getDouble ( object obj )
2007-05-29 20:27:08 +04:00
{
return getShort ( obj ) ;
}
2007-09-24 15:57:00 +04:00
public sealed override object get ( object obj )
2007-05-29 20:27:08 +04:00
{
return jlShort . valueOf ( getShort ( obj ) ) ;
}
2007-09-24 15:57:00 +04:00
public sealed override void set ( object obj , object val )
2007-05-29 20:27:08 +04:00
{
if ( val is jlByte
| | val is jlShort )
setShort ( obj , ( ( jlNumber ) val ) . shortValue ( ) ) ;
else
2009-06-02 10:26:42 +04:00
throw SetIllegalArgumentException ( val ) ;
2007-05-29 20:27:08 +04:00
}
2007-09-24 15:57:00 +04:00
public sealed override void setByte ( object obj , byte b )
2007-05-29 20:27:08 +04:00
{
setShort ( obj , ( sbyte ) b ) ;
}
}
2007-09-24 15:57:00 +04:00
private class IntField : FieldAccessorImplBase
2007-05-29 20:27:08 +04:00
{
internal IntField ( jlrField field , bool overrideAccessCheck )
: base ( field , overrideAccessCheck )
{
}
2007-09-24 15:57:00 +04:00
public sealed override long getLong ( object obj )
2007-05-29 20:27:08 +04:00
{
return getInt ( obj ) ;
}
2007-09-24 15:57:00 +04:00
public sealed override float getFloat ( object obj )
2007-05-29 20:27:08 +04:00
{
return getInt ( obj ) ;
}
2007-09-24 15:57:00 +04:00
public sealed override double getDouble ( object obj )
2007-05-29 20:27:08 +04:00
{
return getInt ( obj ) ;
}
2007-09-24 15:57:00 +04:00
public sealed override object get ( object obj )
2007-05-29 20:27:08 +04:00
{
return jlInteger . valueOf ( getInt ( obj ) ) ;
}
2007-09-24 15:57:00 +04:00
public sealed override void set ( object obj , object val )
2007-05-29 20:27:08 +04:00
{
if ( val is jlByte
| | val is jlShort
| | val is jlInteger )
setInt ( obj , ( ( jlNumber ) val ) . intValue ( ) ) ;
else if ( val is jlCharacter )
setInt ( obj , ( ( jlCharacter ) val ) . charValue ( ) ) ;
else
2009-06-02 10:26:42 +04:00
throw SetIllegalArgumentException ( val ) ;
2007-05-29 20:27:08 +04:00
}
2007-09-24 15:57:00 +04:00
public sealed override void setByte ( object obj , byte b )
2007-05-29 20:27:08 +04:00
{
setInt ( obj , ( sbyte ) b ) ;
}
2007-09-24 15:57:00 +04:00
public sealed override void setChar ( object obj , char c )
2007-05-29 20:27:08 +04:00
{
setInt ( obj , c ) ;
}
2007-09-24 15:57:00 +04:00
public sealed override void setShort ( object obj , short s )
2007-05-29 20:27:08 +04:00
{
setInt ( obj , s ) ;
}
}
2007-09-24 15:57:00 +04:00
private class FloatField : FieldAccessorImplBase
2007-05-29 20:27:08 +04:00
{
internal FloatField ( jlrField field , bool overrideAccessCheck )
: base ( field , overrideAccessCheck )
{
}
2007-09-24 15:57:00 +04:00
public sealed override double getDouble ( object obj )
2007-05-29 20:27:08 +04:00
{
return getFloat ( obj ) ;
}
2007-09-24 15:57:00 +04:00
public sealed override object get ( object obj )
2007-05-29 20:27:08 +04:00
{
return jlFloat . valueOf ( getFloat ( obj ) ) ;
}
2007-09-24 15:57:00 +04:00
public sealed override void set ( object obj , object val )
2007-05-29 20:27:08 +04:00
{
if ( val is jlFloat
| | val is jlByte
| | val is jlShort
| | val is jlInteger
| | val is jlLong )
setFloat ( obj , ( ( jlNumber ) val ) . floatValue ( ) ) ;
else if ( val is jlCharacter )
setFloat ( obj , ( ( jlCharacter ) val ) . charValue ( ) ) ;
else
2009-06-02 10:26:42 +04:00
throw SetIllegalArgumentException ( val ) ;
2007-05-29 20:27:08 +04:00
}
2007-09-24 15:57:00 +04:00
public sealed override void setByte ( object obj , byte b )
2007-05-29 20:27:08 +04:00
{
setFloat ( obj , ( sbyte ) b ) ;
}
2007-09-24 15:57:00 +04:00
public sealed override void setChar ( object obj , char c )
2007-05-29 20:27:08 +04:00
{
setFloat ( obj , c ) ;
}
2007-09-24 15:57:00 +04:00
public sealed override void setShort ( object obj , short s )
2007-05-29 20:27:08 +04:00
{
setFloat ( obj , s ) ;
}
2007-09-24 15:57:00 +04:00
public sealed override void setInt ( object obj , int i )
2007-05-29 20:27:08 +04:00
{
setFloat ( obj , i ) ;
}
2007-09-24 15:57:00 +04:00
public sealed override void setLong ( object obj , long l )
2007-05-29 20:27:08 +04:00
{
setFloat ( obj , l ) ;
}
}
2007-09-24 15:57:00 +04:00
private class LongField : FieldAccessorImplBase
2007-05-29 20:27:08 +04:00
{
internal LongField ( jlrField field , bool overrideAccessCheck )
: base ( field , overrideAccessCheck )
{
}
2007-09-24 15:57:00 +04:00
public sealed override float getFloat ( object obj )
2007-05-29 20:27:08 +04:00
{
return getLong ( obj ) ;
}
2007-09-24 15:57:00 +04:00
public sealed override double getDouble ( object obj )
2007-05-29 20:27:08 +04:00
{
return getLong ( obj ) ;
}
2007-09-24 15:57:00 +04:00
public sealed override object get ( object obj )
2007-05-29 20:27:08 +04:00
{
return jlLong . valueOf ( getLong ( obj ) ) ;
}
2007-09-24 15:57:00 +04:00
public sealed override void set ( object obj , object val )
2007-05-29 20:27:08 +04:00
{
if ( val is jlLong
| | val is jlByte
| | val is jlShort
| | val is jlInteger )
setLong ( obj , ( ( jlNumber ) val ) . longValue ( ) ) ;
else if ( val is jlCharacter )
setLong ( obj , ( ( jlCharacter ) val ) . charValue ( ) ) ;
else
2009-06-02 10:26:42 +04:00
throw SetIllegalArgumentException ( val ) ;
2007-05-29 20:27:08 +04:00
}
2007-09-24 15:57:00 +04:00
public sealed override void setByte ( object obj , byte b )
2007-05-29 20:27:08 +04:00
{
setLong ( obj , ( sbyte ) b ) ;
}
2007-09-24 15:57:00 +04:00
public sealed override void setChar ( object obj , char c )
2007-05-29 20:27:08 +04:00
{
setLong ( obj , c ) ;
}
2007-09-24 15:57:00 +04:00
public sealed override void setShort ( object obj , short s )
2007-05-29 20:27:08 +04:00
{
setLong ( obj , s ) ;
}
2007-09-24 15:57:00 +04:00
public sealed override void setInt ( object obj , int i )
2007-05-29 20:27:08 +04:00
{
setLong ( obj , i ) ;
}
}
2007-09-24 15:57:00 +04:00
private class DoubleField : FieldAccessorImplBase
2007-05-29 20:27:08 +04:00
{
internal DoubleField ( jlrField field , bool overrideAccessCheck )
: base ( field , overrideAccessCheck )
{
}
public override object get ( object obj )
{
return jlDouble . valueOf ( getDouble ( obj ) ) ;
}
public override void set ( object obj , object val )
{
if ( val is jlDouble
| | val is jlFloat
| | val is jlByte
| | val is jlShort
| | val is jlInteger
| | val is jlLong )
setDouble ( obj , ( ( jlNumber ) val ) . doubleValue ( ) ) ;
else if ( val is jlCharacter )
setDouble ( obj , ( ( jlCharacter ) val ) . charValue ( ) ) ;
else
2009-06-02 10:26:42 +04:00
throw SetIllegalArgumentException ( val ) ;
2007-05-29 20:27:08 +04:00
}
public override void setByte ( object obj , byte b )
{
setDouble ( obj , ( sbyte ) b ) ;
}
public override void setChar ( object obj , char c )
{
setDouble ( obj , c ) ;
}
public override void setShort ( object obj , short s )
{
setDouble ( obj , s ) ;
}
public override void setInt ( object obj , int i )
{
setDouble ( obj , i ) ;
}
public override void setLong ( object obj , long l )
{
setDouble ( obj , l ) ;
}
public override void setFloat ( object obj , float f )
{
setDouble ( obj , f ) ;
}
}
2009-06-02 10:26:42 +04:00
private Delegate GenerateFastGetter ( Type delegateType , Type fieldType , FieldWrapper fw )
2007-05-29 20:27:08 +04:00
{
2007-09-24 15:57:00 +04:00
fw . FieldTypeWrapper . Finish ( ) ;
fw . DeclaringType . Finish ( ) ;
fw . ResolveField ( ) ;
2009-06-02 10:26:42 +04:00
DynamicMethod dm = DynamicMethodUtils . Create ( "__<Getter>" , fw . DeclaringType . TypeAsBaseType , ! fw . IsPublic | | ! fw . DeclaringType . IsPublic , fieldType , new Type [ ] { typeof ( IReflectionException ) , typeof ( object ) } ) ;
2008-06-03 16:10:07 +04:00
CodeEmitter ilgen = CodeEmitter . Create ( dm ) ;
2007-09-24 15:57:00 +04:00
if ( fw . IsStatic )
{
fw . EmitGet ( ilgen ) ;
2007-10-10 09:30:04 +04:00
fw . FieldTypeWrapper . EmitConvSignatureTypeToStackType ( ilgen ) ;
2007-09-24 15:57:00 +04:00
}
else
{
ilgen . BeginExceptionBlock ( ) ;
2009-06-02 10:26:42 +04:00
ilgen . Emit ( OpCodes . Ldarg_1 ) ;
2009-03-16 08:28:11 +03:00
ilgen . Emit ( OpCodes . Castclass , fw . DeclaringType . TypeAsBaseType ) ;
2007-09-24 15:57:00 +04:00
fw . EmitGet ( ilgen ) ;
fw . FieldTypeWrapper . EmitConvSignatureTypeToStackType ( ilgen ) ;
LocalBuilder local = ilgen . DeclareLocal ( fieldType ) ;
ilgen . Emit ( OpCodes . Stloc , local ) ;
ilgen . BeginCatchBlock ( typeof ( InvalidCastException ) ) ;
2009-06-02 10:26:42 +04:00
ilgen . Emit ( OpCodes . Ldarg_0 ) ;
ilgen . Emit ( OpCodes . Ldarg_1 ) ;
ilgen . Emit ( OpCodes . Callvirt , typeof ( IReflectionException ) . GetMethod ( "GetIllegalArgumentException" ) ) ;
ilgen . Emit ( OpCodes . Throw ) ;
2007-09-24 15:57:00 +04:00
ilgen . EndExceptionBlock ( ) ;
ilgen . Emit ( OpCodes . Ldloc , local ) ;
}
ilgen . Emit ( OpCodes . Ret ) ;
2009-06-02 10:26:42 +04:00
return dm . CreateDelegate ( delegateType , this ) ;
2007-09-24 15:57:00 +04:00
}
2009-06-02 10:26:42 +04:00
private Delegate GenerateFastSetter ( Type delegateType , Type fieldType , FieldWrapper fw )
2007-09-24 15:57:00 +04:00
{
fw . FieldTypeWrapper . Finish ( ) ;
fw . DeclaringType . Finish ( ) ;
fw . ResolveField ( ) ;
2009-06-02 10:26:42 +04:00
DynamicMethod dm = DynamicMethodUtils . Create ( "__<Setter>" , fw . DeclaringType . TypeAsBaseType , ! fw . IsPublic | | ! fw . DeclaringType . IsPublic , null , new Type [ ] { typeof ( IReflectionException ) , typeof ( object ) , fieldType } ) ;
2008-06-03 16:10:07 +04:00
CodeEmitter ilgen = CodeEmitter . Create ( dm ) ;
2007-09-24 15:57:00 +04:00
if ( fw . IsStatic )
{
if ( fieldType = = typeof ( object ) )
{
ilgen . BeginExceptionBlock ( ) ;
2009-06-02 10:26:42 +04:00
ilgen . Emit ( OpCodes . Ldarg_2 ) ;
2007-09-24 15:57:00 +04:00
fw . FieldTypeWrapper . EmitConvStackTypeToSignatureType ( ilgen , null ) ;
fw . EmitSet ( ilgen ) ;
ilgen . BeginCatchBlock ( typeof ( InvalidCastException ) ) ;
2009-06-02 10:26:42 +04:00
ilgen . Emit ( OpCodes . Ldarg_0 ) ;
ilgen . Emit ( OpCodes . Ldarg_1 ) ;
ilgen . Emit ( OpCodes . Callvirt , typeof ( IReflectionException ) . GetMethod ( "SetIllegalArgumentException" ) ) ;
ilgen . Emit ( OpCodes . Throw ) ;
2007-09-24 15:57:00 +04:00
ilgen . EndExceptionBlock ( ) ;
}
else
{
2009-06-02 10:26:42 +04:00
ilgen . Emit ( OpCodes . Ldarg_2 ) ;
2007-09-24 15:57:00 +04:00
fw . EmitSet ( ilgen ) ;
}
}
else
{
ilgen . BeginExceptionBlock ( ) ;
ilgen . Emit ( OpCodes . Ldarg_1 ) ;
2009-06-02 10:26:42 +04:00
ilgen . Emit ( OpCodes . Castclass , fw . DeclaringType . TypeAsBaseType ) ;
ilgen . Emit ( OpCodes . Ldarg_2 ) ;
2007-09-24 15:57:00 +04:00
fw . FieldTypeWrapper . EmitConvStackTypeToSignatureType ( ilgen , null ) ;
fw . EmitSet ( ilgen ) ;
ilgen . BeginCatchBlock ( typeof ( InvalidCastException ) ) ;
2009-06-02 10:26:42 +04:00
ilgen . Emit ( OpCodes . Ldarg_0 ) ;
ilgen . Emit ( OpCodes . Ldarg_1 ) ;
ilgen . Emit ( OpCodes . Callvirt , typeof ( IReflectionException ) . GetMethod ( "SetIllegalArgumentException" ) ) ;
ilgen . Emit ( OpCodes . Throw ) ;
2007-09-24 15:57:00 +04:00
ilgen . EndExceptionBlock ( ) ;
}
ilgen . Emit ( OpCodes . Ret ) ;
2009-06-02 10:26:42 +04:00
return dm . CreateDelegate ( delegateType , this ) ;
2007-09-24 15:57:00 +04:00
}
private sealed class FastByteFieldAccessor : ByteField
{
private delegate void Setter ( object obj , byte value ) ;
private delegate byte Getter ( object obj ) ;
private Setter setter ;
private Getter getter ;
internal FastByteFieldAccessor ( jlrField field , bool overrideAccessCheck )
: base ( field , overrideAccessCheck )
{
setter = new Setter ( lazySet ) ;
getter = new Getter ( lazyGet ) ;
}
private byte lazyGet ( object obj )
{
2008-09-25 09:17:21 +04:00
// FXBUG it appears that a ldsfld/stsfld in a DynamicMethod doesn't trigger the class constructor
fw . DeclaringType . RunClassInit ( ) ;
2007-09-24 15:57:00 +04:00
getter = ( Getter ) GenerateFastGetter ( typeof ( Getter ) , typeof ( byte ) , fw ) ;
return getter ( obj ) ;
}
private void lazySet ( object obj , byte value )
{
2008-09-25 09:17:21 +04:00
// FXBUG it appears that a ldsfld/stsfld in a DynamicMethod doesn't trigger the class constructor
fw . DeclaringType . RunClassInit ( ) ;
2007-09-24 15:57:00 +04:00
if ( isFinal )
{
2009-06-02 10:26:42 +04:00
throw FinalFieldIllegalAccessException ( jlByte . valueOf ( value ) ) ;
2007-09-24 15:57:00 +04:00
}
setter = ( Setter ) GenerateFastSetter ( typeof ( Setter ) , typeof ( byte ) , fw ) ;
setter ( obj , value ) ;
}
public override byte getByte ( object obj )
{
return getter ( obj ) ;
}
public override void setByte ( object obj , byte value )
{
setter ( obj , value ) ;
}
}
private sealed class FastBooleanFieldAccessor : BooleanField
{
private delegate void Setter ( object obj , bool value ) ;
private delegate bool Getter ( object obj ) ;
private Setter setter ;
private Getter getter ;
internal FastBooleanFieldAccessor ( jlrField field , bool overrideAccessCheck )
: base ( field , overrideAccessCheck )
{
setter = new Setter ( lazySet ) ;
getter = new Getter ( lazyGet ) ;
}
private bool lazyGet ( object obj )
{
2008-09-25 09:17:21 +04:00
// FXBUG it appears that a ldsfld/stsfld in a DynamicMethod doesn't trigger the class constructor
fw . DeclaringType . RunClassInit ( ) ;
2007-09-24 15:57:00 +04:00
getter = ( Getter ) GenerateFastGetter ( typeof ( Getter ) , typeof ( bool ) , fw ) ;
return getter ( obj ) ;
}
private void lazySet ( object obj , bool value )
{
2008-09-25 09:17:21 +04:00
// FXBUG it appears that a ldsfld/stsfld in a DynamicMethod doesn't trigger the class constructor
fw . DeclaringType . RunClassInit ( ) ;
2007-09-24 15:57:00 +04:00
if ( isFinal )
{
2009-06-02 10:26:42 +04:00
throw FinalFieldIllegalAccessException ( jlBoolean . valueOf ( value ) ) ;
2007-09-24 15:57:00 +04:00
}
setter = ( Setter ) GenerateFastSetter ( typeof ( Setter ) , typeof ( bool ) , fw ) ;
setter ( obj , value ) ;
}
public override bool getBoolean ( object obj )
{
return getter ( obj ) ;
}
public override void setBoolean ( object obj , bool value )
{
setter ( obj , value ) ;
}
}
private sealed class FastCharFieldAccessor : CharField
{
private delegate void Setter ( object obj , char value ) ;
private delegate char Getter ( object obj ) ;
private Setter setter ;
private Getter getter ;
internal FastCharFieldAccessor ( jlrField field , bool overrideAccessCheck )
: base ( field , overrideAccessCheck )
{
setter = new Setter ( lazySet ) ;
getter = new Getter ( lazyGet ) ;
}
private char lazyGet ( object obj )
{
2008-09-25 09:17:21 +04:00
// FXBUG it appears that a ldsfld/stsfld in a DynamicMethod doesn't trigger the class constructor
fw . DeclaringType . RunClassInit ( ) ;
2007-09-24 15:57:00 +04:00
getter = ( Getter ) GenerateFastGetter ( typeof ( Getter ) , typeof ( char ) , fw ) ;
return getter ( obj ) ;
}
private void lazySet ( object obj , char value )
{
2008-09-25 09:17:21 +04:00
// FXBUG it appears that a ldsfld/stsfld in a DynamicMethod doesn't trigger the class constructor
fw . DeclaringType . RunClassInit ( ) ;
2007-09-24 15:57:00 +04:00
if ( isFinal )
{
2009-06-02 10:26:42 +04:00
throw FinalFieldIllegalAccessException ( jlCharacter . valueOf ( value ) ) ;
2007-09-24 15:57:00 +04:00
}
setter = ( Setter ) GenerateFastSetter ( typeof ( Setter ) , typeof ( char ) , fw ) ;
setter ( obj , value ) ;
}
public override char getChar ( object obj )
{
return getter ( obj ) ;
}
public override void setChar ( object obj , char value )
{
setter ( obj , value ) ;
}
}
private sealed class FastShortFieldAccessor : ShortField
{
private delegate void Setter ( object obj , short value ) ;
private delegate short Getter ( object obj ) ;
private Setter setter ;
private Getter getter ;
internal FastShortFieldAccessor ( jlrField field , bool overrideAccessCheck )
: base ( field , overrideAccessCheck )
{
setter = new Setter ( lazySet ) ;
getter = new Getter ( lazyGet ) ;
}
private short lazyGet ( object obj )
{
2008-09-25 09:17:21 +04:00
// FXBUG it appears that a ldsfld/stsfld in a DynamicMethod doesn't trigger the class constructor
fw . DeclaringType . RunClassInit ( ) ;
2007-09-24 15:57:00 +04:00
getter = ( Getter ) GenerateFastGetter ( typeof ( Getter ) , typeof ( short ) , fw ) ;
return getter ( obj ) ;
}
private void lazySet ( object obj , short value )
{
2008-09-25 09:17:21 +04:00
// FXBUG it appears that a ldsfld/stsfld in a DynamicMethod doesn't trigger the class constructor
fw . DeclaringType . RunClassInit ( ) ;
2007-09-24 15:57:00 +04:00
if ( isFinal )
{
2009-06-02 10:26:42 +04:00
throw FinalFieldIllegalAccessException ( jlShort . valueOf ( value ) ) ;
2007-09-24 15:57:00 +04:00
}
setter = ( Setter ) GenerateFastSetter ( typeof ( Setter ) , typeof ( short ) , fw ) ;
setter ( obj , value ) ;
}
public override short getShort ( object obj )
{
return getter ( obj ) ;
}
public override void setShort ( object obj , short value )
{
setter ( obj , value ) ;
}
}
private sealed class FastIntegerFieldAccessor : IntField
{
private delegate void Setter ( object obj , int value ) ;
private delegate int Getter ( object obj ) ;
private Setter setter ;
private Getter getter ;
internal FastIntegerFieldAccessor ( jlrField field , bool overrideAccessCheck )
: base ( field , overrideAccessCheck )
{
setter = new Setter ( lazySet ) ;
getter = new Getter ( lazyGet ) ;
}
private int lazyGet ( object obj )
{
2008-09-25 09:17:21 +04:00
// FXBUG it appears that a ldsfld/stsfld in a DynamicMethod doesn't trigger the class constructor
fw . DeclaringType . RunClassInit ( ) ;
2007-09-24 15:57:00 +04:00
getter = ( Getter ) GenerateFastGetter ( typeof ( Getter ) , typeof ( int ) , fw ) ;
return getter ( obj ) ;
}
private void lazySet ( object obj , int value )
{
2008-09-25 09:17:21 +04:00
// FXBUG it appears that a ldsfld/stsfld in a DynamicMethod doesn't trigger the class constructor
fw . DeclaringType . RunClassInit ( ) ;
2007-09-24 15:57:00 +04:00
if ( isFinal )
{
2009-06-02 10:26:42 +04:00
throw FinalFieldIllegalAccessException ( jlInteger . valueOf ( value ) ) ;
2007-09-24 15:57:00 +04:00
}
setter = ( Setter ) GenerateFastSetter ( typeof ( Setter ) , typeof ( int ) , fw ) ;
setter ( obj , value ) ;
}
public override int getInt ( object obj )
{
return getter ( obj ) ;
}
public override void setInt ( object obj , int value )
{
setter ( obj , value ) ;
}
}
private sealed class FastFloatFieldAccessor : FloatField
{
private delegate void Setter ( object obj , float value ) ;
private delegate float Getter ( object obj ) ;
private Setter setter ;
private Getter getter ;
internal FastFloatFieldAccessor ( jlrField field , bool overrideAccessCheck )
: base ( field , overrideAccessCheck )
{
setter = new Setter ( lazySet ) ;
getter = new Getter ( lazyGet ) ;
}
private float lazyGet ( object obj )
{
2008-09-25 09:17:21 +04:00
// FXBUG it appears that a ldsfld/stsfld in a DynamicMethod doesn't trigger the class constructor
fw . DeclaringType . RunClassInit ( ) ;
2007-09-24 15:57:00 +04:00
getter = ( Getter ) GenerateFastGetter ( typeof ( Getter ) , typeof ( float ) , fw ) ;
return getter ( obj ) ;
}
private void lazySet ( object obj , float value )
{
2008-09-25 09:17:21 +04:00
// FXBUG it appears that a ldsfld/stsfld in a DynamicMethod doesn't trigger the class constructor
fw . DeclaringType . RunClassInit ( ) ;
2007-09-24 15:57:00 +04:00
if ( isFinal )
{
2009-06-02 10:26:42 +04:00
throw FinalFieldIllegalAccessException ( jlFloat . valueOf ( value ) ) ;
2007-09-24 15:57:00 +04:00
}
setter = ( Setter ) GenerateFastSetter ( typeof ( Setter ) , typeof ( float ) , fw ) ;
setter ( obj , value ) ;
}
public override float getFloat ( object obj )
{
return getter ( obj ) ;
}
public override void setFloat ( object obj , float value )
{
setter ( obj , value ) ;
}
}
private sealed class FastLongFieldAccessor : LongField
{
private delegate void Setter ( object obj , long value ) ;
private delegate long Getter ( object obj ) ;
private Setter setter ;
private Getter getter ;
internal FastLongFieldAccessor ( jlrField field , bool overrideAccessCheck )
: base ( field , overrideAccessCheck )
{
setter = new Setter ( lazySet ) ;
getter = new Getter ( lazyGet ) ;
}
private long lazyGet ( object obj )
{
2008-09-25 09:17:21 +04:00
// FXBUG it appears that a ldsfld/stsfld in a DynamicMethod doesn't trigger the class constructor
fw . DeclaringType . RunClassInit ( ) ;
2007-09-24 15:57:00 +04:00
getter = ( Getter ) GenerateFastGetter ( typeof ( Getter ) , typeof ( long ) , fw ) ;
return getter ( obj ) ;
}
private void lazySet ( object obj , long value )
{
2008-09-25 09:17:21 +04:00
// FXBUG it appears that a ldsfld/stsfld in a DynamicMethod doesn't trigger the class constructor
fw . DeclaringType . RunClassInit ( ) ;
2007-09-24 15:57:00 +04:00
if ( isFinal )
{
2009-06-02 10:26:42 +04:00
throw FinalFieldIllegalAccessException ( jlLong . valueOf ( value ) ) ;
2007-09-24 15:57:00 +04:00
}
setter = ( Setter ) GenerateFastSetter ( typeof ( Setter ) , typeof ( long ) , fw ) ;
setter ( obj , value ) ;
}
public override long getLong ( object obj )
{
return getter ( obj ) ;
}
public override void setLong ( object obj , long value )
{
setter ( obj , value ) ;
}
}
private sealed class FastDoubleFieldAccessor : DoubleField
{
private delegate void Setter ( object obj , double value ) ;
private delegate double Getter ( object obj ) ;
private Setter setter ;
private Getter getter ;
internal FastDoubleFieldAccessor ( jlrField field , bool overrideAccessCheck )
: base ( field , overrideAccessCheck )
{
setter = new Setter ( lazySet ) ;
getter = new Getter ( lazyGet ) ;
}
private double lazyGet ( object obj )
{
2008-09-25 09:17:21 +04:00
// FXBUG it appears that a ldsfld/stsfld in a DynamicMethod doesn't trigger the class constructor
fw . DeclaringType . RunClassInit ( ) ;
2007-09-24 15:57:00 +04:00
getter = ( Getter ) GenerateFastGetter ( typeof ( Getter ) , typeof ( double ) , fw ) ;
return getter ( obj ) ;
}
private void lazySet ( object obj , double value )
{
2008-09-25 09:17:21 +04:00
// FXBUG it appears that a ldsfld/stsfld in a DynamicMethod doesn't trigger the class constructor
fw . DeclaringType . RunClassInit ( ) ;
2007-09-24 15:57:00 +04:00
if ( isFinal )
{
2009-06-02 10:26:42 +04:00
throw FinalFieldIllegalAccessException ( jlDouble . valueOf ( value ) ) ;
2007-09-24 15:57:00 +04:00
}
setter = ( Setter ) GenerateFastSetter ( typeof ( Setter ) , typeof ( double ) , fw ) ;
setter ( obj , value ) ;
}
public override double getDouble ( object obj )
{
return getter ( obj ) ;
}
public override void setDouble ( object obj , double value )
{
setter ( obj , value ) ;
}
}
private sealed class FastObjectFieldAccessor : ObjectField
{
private delegate void Setter ( object obj , object value ) ;
private delegate object Getter ( object obj ) ;
private Setter setter ;
private Getter getter ;
internal FastObjectFieldAccessor ( jlrField field , bool overrideAccessCheck )
: base ( field , overrideAccessCheck )
{
setter = new Setter ( lazySet ) ;
getter = new Getter ( lazyGet ) ;
}
private object lazyGet ( object obj )
{
2008-09-25 09:17:21 +04:00
// FXBUG it appears that a ldsfld/stsfld in a DynamicMethod doesn't trigger the class constructor
fw . DeclaringType . RunClassInit ( ) ;
2007-09-24 15:57:00 +04:00
getter = ( Getter ) GenerateFastGetter ( typeof ( Getter ) , typeof ( object ) , fw ) ;
return getter ( obj ) ;
}
private void lazySet ( object obj , object value )
{
2008-09-25 09:17:21 +04:00
// FXBUG it appears that a ldsfld/stsfld in a DynamicMethod doesn't trigger the class constructor
fw . DeclaringType . RunClassInit ( ) ;
2007-09-24 15:57:00 +04:00
if ( isFinal )
{
2009-06-02 10:26:42 +04:00
throw FinalFieldIllegalAccessException ( value ) ;
2007-09-24 15:57:00 +04:00
}
setter = ( Setter ) GenerateFastSetter ( typeof ( Setter ) , typeof ( object ) , fw ) ;
setter ( obj , value ) ;
}
public override object get ( object obj )
{
return getter ( obj ) ;
}
public override void set ( object obj , object value )
{
setter ( obj , value ) ;
}
}
internal static FieldAccessorImplBase Create ( jlrField field , bool overrideAccessCheck )
{
jlClass type = field . getType ( ) ;
if ( type . isPrimitive ( ) )
{
if ( type = = jlByte . TYPE )
{
2008-08-21 10:53:48 +04:00
return new FastByteFieldAccessor ( field , overrideAccessCheck ) ;
2007-09-24 15:57:00 +04:00
}
if ( type = = jlBoolean . TYPE )
{
2008-08-21 10:53:48 +04:00
return new FastBooleanFieldAccessor ( field , overrideAccessCheck ) ;
2007-09-24 15:57:00 +04:00
}
if ( type = = jlCharacter . TYPE )
{
2008-08-21 10:53:48 +04:00
return new FastCharFieldAccessor ( field , overrideAccessCheck ) ;
2007-09-24 15:57:00 +04:00
}
if ( type = = jlShort . TYPE )
{
2008-08-21 10:53:48 +04:00
return new FastShortFieldAccessor ( field , overrideAccessCheck ) ;
2007-09-24 15:57:00 +04:00
}
if ( type = = jlInteger . TYPE )
{
2008-08-21 10:53:48 +04:00
return new FastIntegerFieldAccessor ( field , overrideAccessCheck ) ;
2007-09-24 15:57:00 +04:00
}
if ( type = = jlFloat . TYPE )
{
2008-08-21 10:53:48 +04:00
return new FastFloatFieldAccessor ( field , overrideAccessCheck ) ;
2007-09-24 15:57:00 +04:00
}
if ( type = = jlLong . TYPE )
{
2008-08-21 10:53:48 +04:00
return new FastLongFieldAccessor ( field , overrideAccessCheck ) ;
2007-09-24 15:57:00 +04:00
}
if ( type = = jlDouble . TYPE )
{
2008-08-21 10:53:48 +04:00
return new FastDoubleFieldAccessor ( field , overrideAccessCheck ) ;
2007-09-24 15:57:00 +04:00
}
throw new InvalidOperationException ( "field type: " + type ) ;
}
else
{
2008-08-21 10:53:48 +04:00
return new FastObjectFieldAccessor ( field , overrideAccessCheck ) ;
2007-09-24 15:57:00 +04:00
}
}
}
#endif
2007-05-29 20:27:08 +04:00
public static object newFieldAccessor ( object thisFactory , object field , bool overrideAccessCheck )
{
#if FIRST_PASS
return null ;
#else
return FieldAccessorImplBase . Create ( ( jlrField ) field , overrideAccessCheck ) ;
#endif
}
public static object newMethodAccessor ( object thisFactory , object method )
{
#if FIRST_PASS
return null ;
#else
2007-09-24 15:57:00 +04:00
jlrMethod m = ( jlrMethod ) method ;
2008-08-21 10:53:48 +04:00
MethodWrapper mw = MethodWrapper . FromMethodOrConstructor ( method ) ;
if ( mw is ICustomInvoke )
2007-09-24 15:57:00 +04:00
{
2008-08-21 10:53:48 +04:00
return new MethodAccessorImpl ( m ) ;
}
else
{
return new FastMethodAccessorImpl ( m , false ) ;
2007-09-24 15:57:00 +04:00
}
2007-05-29 20:27:08 +04:00
#endif
}
public static object newConstructorAccessor0 ( object thisFactory , object constructor )
{
#if FIRST_PASS
return null ;
#else
2007-09-24 15:57:00 +04:00
jlrConstructor cons = ( jlrConstructor ) constructor ;
2008-08-21 10:53:48 +04:00
MethodWrapper mw = MethodWrapper . FromMethodOrConstructor ( constructor ) ;
if ( mw is ICustomInvoke )
2007-09-24 15:57:00 +04:00
{
2008-08-21 10:53:48 +04:00
return new ConstructorAccessorImpl ( cons ) ;
2007-09-24 15:57:00 +04:00
}
2009-02-25 08:02:35 +03:00
else if ( ActivatorConstructorAccessor . IsSuitable ( mw ) )
{
// we special case public default constructors, because in that case using Activator.CreateInstance()
// is almost as fast as FastConstructorAccessorImpl, but it saves us significantly in working set and
// startup time (because often during startup a sun.nio.cs.* encoder is instantiated using reflection)
return new ActivatorConstructorAccessor ( mw ) ;
}
2007-09-24 15:57:00 +04:00
else
{
2008-08-21 10:53:48 +04:00
return new FastConstructorAccessorImpl ( cons ) ;
2007-09-24 15:57:00 +04:00
}
2007-05-29 20:27:08 +04:00
#endif
}
2007-05-28 14:15:23 +04:00
2007-05-29 20:27:08 +04:00
public static object newConstructorAccessorForSerialization ( object classToInstantiate , object constructorToCall )
2007-05-28 14:15:23 +04:00
{
2007-06-19 10:09:13 +04:00
#if FIRST_PASS
return null ;
#else
2007-09-24 15:57:00 +04:00
jlrConstructor cons = ( jlrConstructor ) constructorToCall ;
2008-08-21 10:53:48 +04:00
return new FastSerializationConstructorAccessorImpl ( cons , ( jlClass ) classToInstantiate ) ;
2007-06-19 10:09:13 +04:00
#endif
2007-05-28 14:15:23 +04:00
}
}
2007-12-18 14:05:30 +03:00
static class ConstantPool
2007-05-28 14:15:23 +04:00
{
public static int getSize0 ( object thisConstantPool , object constantPoolOop )
{
throw new NotImplementedException ( ) ;
}
public static object getClassAt0 ( object thisConstantPool , object constantPoolOop , int index )
{
throw new NotImplementedException ( ) ;
}
public static object getClassAtIfLoaded0 ( object thisConstantPool , object constantPoolOop , int index )
{
throw new NotImplementedException ( ) ;
}
public static object getMethodAt0 ( object thisConstantPool , object constantPoolOop , int index )
{
throw new NotImplementedException ( ) ;
}
public static object getMethodAtIfLoaded0 ( object thisConstantPool , object constantPoolOop , int index )
{
throw new NotImplementedException ( ) ;
}
public static object getFieldAt0 ( object thisConstantPool , object constantPoolOop , int index )
{
throw new NotImplementedException ( ) ;
}
public static object getFieldAtIfLoaded0 ( object thisConstantPool , object constantPoolOop , int index )
{
throw new NotImplementedException ( ) ;
}
public static string [ ] getMemberRefInfoAt0 ( object thisConstantPool , object constantPoolOop , int index )
{
throw new NotImplementedException ( ) ;
}
public static int getIntAt0 ( object thisConstantPool , object constantPoolOop , int index )
{
2008-03-03 11:28:22 +03:00
throw new NotImplementedException ( ) ;
2007-05-28 14:15:23 +04:00
}
public static long getLongAt0 ( object thisConstantPool , object constantPoolOop , int index )
{
2008-03-03 11:28:22 +03:00
throw new NotImplementedException ( ) ;
2007-05-28 14:15:23 +04:00
}
public static float getFloatAt0 ( object thisConstantPool , object constantPoolOop , int index )
{
2008-03-03 11:28:22 +03:00
throw new NotImplementedException ( ) ;
2007-05-28 14:15:23 +04:00
}
public static double getDoubleAt0 ( object thisConstantPool , object constantPoolOop , int index )
{
2008-03-03 11:28:22 +03:00
throw new NotImplementedException ( ) ;
2007-05-28 14:15:23 +04:00
}
public static string getStringAt0 ( object thisConstantPool , object constantPoolOop , int index )
{
throw new NotImplementedException ( ) ;
}
public static string getUTF8At0 ( object thisConstantPool , object constantPoolOop , int index )
{
2008-03-03 11:28:22 +03:00
throw new NotImplementedException ( ) ;
2007-05-28 14:15:23 +04:00
}
}
}
2007-06-13 15:46:24 +04:00
2007-06-22 13:51:42 +04:00
namespace IKVM.NativeCode.sun.rmi.server
{
2007-12-18 14:05:30 +03:00
static class MarshalInputStream
2007-06-22 13:51:42 +04:00
{
public static object latestUserDefinedLoader ( )
{
return java . io . ObjectInputStream . latestUserDefinedLoader ( ) ;
}
}
}
2007-07-12 12:40:32 +04:00
namespace IKVM.NativeCode.sun.security.krb5
{
2007-12-18 14:05:30 +03:00
static class Credentials
2007-07-12 12:40:32 +04:00
{
public static object acquireDefaultNativeCreds ( )
{
// TODO
return null ;
}
}
2007-12-18 14:05:30 +03:00
static class Config
2007-07-12 12:40:32 +04:00
{
public static string getWindowsDirectory ( )
{
return Environment . GetEnvironmentVariable ( "SystemRoot" ) ;
}
}
}
namespace IKVM.NativeCode.sun.security.provider
{
2007-12-18 14:05:30 +03:00
static class NativeSeedGenerator
2007-07-12 12:40:32 +04:00
{
public static bool nativeGenerateSeed ( byte [ ] result )
{
try
{
System . Security . Cryptography . RNGCryptoServiceProvider csp = new System . Security . Cryptography . RNGCryptoServiceProvider ( ) ;
csp . GetBytes ( result ) ;
return true ;
}
catch ( System . Security . Cryptography . CryptographicException )
{
return false ;
}
}
}
}
namespace IKVM.NativeCode.com.sun.java.util.jar.pack
{
2007-12-18 14:05:30 +03:00
static class NativeUnpack
2007-07-12 12:40:32 +04:00
{
public static void initIDs ( )
{
}
public static long start ( object thisNativeUnpack , object buf , long offset )
{
throw new NotImplementedException ( ) ;
}
public static bool getNextFile ( object thisNativeUnpack , object [ ] parts )
{
throw new NotImplementedException ( ) ;
}
public static object getUnusedInput ( object thisNativeUnpack )
{
throw new NotImplementedException ( ) ;
}
public static long finish ( object thisNativeUnpack )
{
throw new NotImplementedException ( ) ;
}
public static bool setOption ( object thisNativeUnpack , string opt , string value )
{
throw new NotImplementedException ( ) ;
}
public static string getOption ( object thisNativeUnpack , string opt )
{
throw new NotImplementedException ( ) ;
}
}
}
namespace IKVM.NativeCode.com.sun.security.auth.module
{
2007-12-18 14:05:30 +03:00
static class NTSystem
2007-07-12 12:40:32 +04:00
{
public static void getCurrent ( object thisObj , bool debug )
{
throw new NotImplementedException ( ) ;
}
}
2007-12-18 14:05:30 +03:00
static class SolarisSystem
2007-07-12 12:40:32 +04:00
{
public static void getSolarisInfo ( object thisObj )
{
throw new NotImplementedException ( ) ;
}
}
2007-12-18 14:05:30 +03:00
static class UnixSystem
2007-07-12 12:40:32 +04:00
{
public static void getUnixInfo ( object thisObj )
{
throw new NotImplementedException ( ) ;
}
}
}
2008-09-21 13:45:00 +04:00
namespace IKVM.NativeCode.com.sun.media.sound
{
static class JDK13Services
{
public static string getDefaultProviderClassName ( object deviceClass )
{
return null ;
}
public static string getDefaultInstanceName ( object deviceClass )
{
return null ;
}
public static object getProviders ( object providerClass )
{
#if FIRST_PASS
return null ;
#else
return new global :: java . util . ArrayList ( ) ;
#endif
}
}
}
2009-03-04 11:18:36 +03:00
2009-04-30 23:52:43 +04:00
namespace IKVM.NativeCode.java.awt
{
2009-05-03 22:44:22 +04:00
static class AWTEvent
{
public static void initIDs ( ) { }
public static void nativeSetSource ( object thisObj , object peer ) { }
}
static class Button
{
public static void initIDs ( ) { }
}
static class Checkbox
{
public static void initIDs ( ) { }
}
static class CheckboxMenuItem
{
public static void initIDs ( ) { }
}
static class Color
{
public static void initIDs ( ) { }
}
static class Component
{
public static void initIDs ( ) { }
}
static class Container
{
public static void initIDs ( ) { }
}
static class Cursor
{
public static void initIDs ( ) { }
public static void finalizeImpl ( Int64 pData ) { }
}
static class Dialog
{
public static void initIDs ( ) { }
}
static class Dimension
{
public static void initIDs ( ) { }
}
static class Event
{
public static void initIDs ( ) { }
}
static class FileDialog
{
public static void initIDs ( ) { }
}
static class Frame
{
public static void initIDs ( ) { }
}
2009-04-30 23:52:43 +04:00
static class FontMetrics
{
public static void initIDs ( ) { }
}
2009-05-03 22:44:22 +04:00
static class Insets
{
public static void initIDs ( ) { }
}
static class KeyboardFocusManager
{
public static void initIDs ( ) { }
}
static class Label
{
public static void initIDs ( ) { }
}
static class Menu
{
public static void initIDs ( ) { }
}
static class MenuBar
{
public static void initIDs ( ) { }
}
static class MenuComponent
{
public static void initIDs ( ) { }
}
static class MenuItem
{
public static void initIDs ( ) { }
}
static class Rectangle
{
public static void initIDs ( ) { }
}
static class Scrollbar
{
public static void initIDs ( ) { }
}
static class ScrollPane
{
public static void initIDs ( ) { }
}
static class ScrollPaneAdjustable
{
public static void initIDs ( ) { }
}
static class SplashScreen
{
public static void _update ( long splashPtr , int [ ] data , int x , int y , int width , int height , int scanlineStride ) { }
public static bool _isVisible ( long splashPtr ) { return false ; }
public static object _getBounds ( long splashPtr ) { return null ; }
public static long _getInstance ( ) { return 0 ; }
public static void _close ( long splashPtr ) { }
public static String _getImageFileName ( long splashPtr ) { return null ; }
public static String _getImageJarName ( long splashPtr ) { return null ; }
public static bool _setImageData ( long splashPtr , byte [ ] data ) { return false ; }
}
static class TextArea
{
public static void initIDs ( ) { }
}
static class TextField
{
public static void initIDs ( ) { }
}
static class Toolkit
{
public static void initIDs ( ) { }
}
static class TrayIcon
{
public static void initIDs ( ) { }
}
static class Window
{
public static void initIDs ( ) { }
}
2009-04-30 23:52:43 +04:00
}
2009-03-04 11:18:36 +03:00
namespace IKVM.NativeCode.java.awt.@event
{
static class InputEvent
{
public static void initIDs ( ) { }
}
static class MouseEvent
{
public static void initIDs ( ) { }
}
static class KeyEvent
{
public static void initIDs ( ) { }
}
}
2009-04-17 10:36:01 +04:00
namespace IKVM.NativeCode.java.awt.image
{
static class ColorModel
{
public static void initIDs ( ) { }
}
static class ComponentSampleModel
{
public static void initIDs ( ) { }
}
static class Kernel
{
public static void initIDs ( ) { }
}
static class Raster
{
public static void initIDs ( ) { }
}
static class SinglePixelPackedSampleModel
{
public static void initIDs ( ) { }
}
static class SampleModel
{
public static void initIDs ( ) { }
}
}