2002-12-18 19:00:25 +03:00
/ *
2006-01-02 11:15:43 +03:00
Copyright ( C ) 2002 , 2003 , 2004 , 2005 , 2006 Jeroen Frijters
2002-12-18 19:00:25 +03: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 ;
using System.Reflection ;
2005-12-07 12:06:32 +03:00
#if ! COMPACT_FRAMEWORK
using System.Reflection.Emit ;
#endif
2002-12-18 19:00:25 +03:00
using System.IO ;
using System.Collections ;
using System.Diagnostics ;
2004-09-09 15:17:55 +04:00
using IKVM.Attributes ;
using IKVM.Runtime ;
2002-12-18 19:00:25 +03:00
2005-06-01 13:49:30 +04:00
namespace IKVM.Internal
2002-12-18 19:00:25 +03:00
{
2006-02-22 17:44:07 +03:00
abstract class ClassLoaderWrapper
2002-12-18 19:00:25 +03:00
{
2005-12-07 12:06:32 +03:00
private static readonly object wrapperLock = new object ( ) ;
#if ! COMPACT_FRAMEWORK
2006-02-22 17:44:07 +03:00
protected static bool arrayConstructionHack ;
protected static readonly object arrayConstructionLock = new object ( ) ;
2005-12-07 12:06:32 +03:00
#endif
2005-09-06 12:06:04 +04:00
private static readonly Hashtable typeToTypeWrapper = Hashtable . Synchronized ( new Hashtable ( ) ) ;
2005-06-01 13:49:30 +04:00
private static ClassLoaderWrapper bootstrapClassLoader ;
2006-05-15 13:08:01 +04:00
#if WHIDBEY & & ! STATIC_COMPILER
private static readonly Hashtable reflectionOnlyClassLoaders = new Hashtable ( ) ;
#endif
2006-04-10 13:09:09 +04:00
#if ! STATIC_COMPILER
2005-06-01 13:49:30 +04:00
private static ClassLoaderWrapper systemClassLoader ;
2006-04-10 13:09:09 +04:00
#endif
2005-06-01 13:49:30 +04:00
private object javaClassLoader ;
2006-02-22 17:44:07 +03:00
protected Hashtable types = new Hashtable ( ) ;
2005-06-01 13:49:30 +04:00
private ArrayList nativeLibraries ;
private static Hashtable remappedTypes = new Hashtable ( ) ;
2002-12-18 19:00:25 +03:00
2005-06-01 13:49:30 +04:00
// HACK this is used by the ahead-of-time compiler to overrule the bootstrap classloader
internal static void SetBootstrapClassLoader ( ClassLoaderWrapper bootstrapClassLoader )
{
Debug . Assert ( ClassLoaderWrapper . bootstrapClassLoader = = null ) ;
2002-12-18 19:00:25 +03:00
2005-06-01 13:49:30 +04:00
ClassLoaderWrapper . bootstrapClassLoader = bootstrapClassLoader ;
}
2004-03-08 18:18:47 +03:00
2005-06-01 13:49:30 +04:00
static ClassLoaderWrapper ( )
{
typeToTypeWrapper [ PrimitiveTypeWrapper . BOOLEAN . TypeAsTBD ] = PrimitiveTypeWrapper . BOOLEAN ;
typeToTypeWrapper [ PrimitiveTypeWrapper . BYTE . TypeAsTBD ] = PrimitiveTypeWrapper . BYTE ;
typeToTypeWrapper [ PrimitiveTypeWrapper . CHAR . TypeAsTBD ] = PrimitiveTypeWrapper . CHAR ;
typeToTypeWrapper [ PrimitiveTypeWrapper . DOUBLE . TypeAsTBD ] = PrimitiveTypeWrapper . DOUBLE ;
typeToTypeWrapper [ PrimitiveTypeWrapper . FLOAT . TypeAsTBD ] = PrimitiveTypeWrapper . FLOAT ;
typeToTypeWrapper [ PrimitiveTypeWrapper . INT . TypeAsTBD ] = PrimitiveTypeWrapper . INT ;
typeToTypeWrapper [ PrimitiveTypeWrapper . LONG . TypeAsTBD ] = PrimitiveTypeWrapper . LONG ;
typeToTypeWrapper [ PrimitiveTypeWrapper . SHORT . TypeAsTBD ] = PrimitiveTypeWrapper . SHORT ;
typeToTypeWrapper [ PrimitiveTypeWrapper . VOID . TypeAsTBD ] = PrimitiveTypeWrapper . VOID ;
LoadRemappedTypes ( ) ;
}
2004-12-21 17:59:29 +03:00
2005-06-01 13:49:30 +04:00
internal static void LoadRemappedTypes ( )
2002-12-18 19:00:25 +03:00
{
2005-12-07 12:06:32 +03:00
// if we're compiling the core, coreAssembly will be null
Assembly coreAssembly = JVM . CoreAssembly ;
if ( coreAssembly ! = null )
2004-03-08 18:18:47 +03:00
{
2005-12-19 18:12:49 +03:00
Tracer . Info ( Tracer . Runtime , "Core assembly: {0}" , coreAssembly . Location ) ;
2005-12-07 12:06:32 +03:00
RemappedClassAttribute [ ] remapped = AttributeHelper . GetRemappedClasses ( coreAssembly ) ;
2005-06-01 13:49:30 +04:00
if ( remapped . Length > 0 )
{
foreach ( RemappedClassAttribute r in remapped )
{
Tracer . Info ( Tracer . Runtime , "Remapping type {0} to {1}" , r . RemappedType , r . Name ) ;
remappedTypes . Add ( r . RemappedType , r . Name ) ;
}
}
else
2004-03-08 18:18:47 +03:00
{
2005-06-01 13:49:30 +04:00
JVM . CriticalFailure ( "Failed to find core classes in core library" , null ) ;
2004-03-08 18:18:47 +03:00
}
}
2002-12-18 19:00:25 +03:00
}
2004-03-08 18:18:47 +03:00
2005-06-01 13:49:30 +04:00
internal static bool IsCoreAssemblyType ( Type type )
{
2005-12-07 12:06:32 +03:00
return type . Assembly = = JVM . CoreAssembly ;
2005-06-01 13:49:30 +04:00
}
2004-10-04 23:30:53 +04:00
2005-06-01 13:49:30 +04:00
internal ClassLoaderWrapper ( object javaClassLoader )
2004-03-08 18:18:47 +03:00
{
2005-06-01 13:49:30 +04:00
SetJavaClassLoader ( javaClassLoader ) ;
2002-12-18 19:00:25 +03:00
}
2005-06-01 13:49:30 +04:00
internal void SetJavaClassLoader ( object javaClassLoader )
2004-08-17 13:05:21 +04:00
{
2005-06-01 13:49:30 +04:00
this . javaClassLoader = javaClassLoader ;
2004-08-17 13:05:21 +04:00
}
2005-06-01 13:49:30 +04:00
internal static bool IsRemappedType ( Type type )
2004-08-17 13:05:21 +04:00
{
2005-06-01 13:49:30 +04:00
return remappedTypes . ContainsKey ( type ) ;
2004-08-17 13:05:21 +04:00
}
2002-12-18 19:00:25 +03:00
2005-06-01 13:49:30 +04:00
internal void SetRemappedType ( Type type , TypeWrapper tw )
{
Debug . Assert ( ! types . ContainsKey ( tw . Name ) ) ;
types . Add ( tw . Name , tw ) ;
Debug . Assert ( ! typeToTypeWrapper . ContainsKey ( type ) ) ;
typeToTypeWrapper . Add ( type , tw ) ;
remappedTypes . Add ( type , type ) ;
}
2002-12-18 19:00:25 +03:00
2005-06-01 13:49:30 +04:00
// HACK return the TypeWrapper if it is already loaded
2005-07-25 18:34:22 +04:00
// (this exists solely for DynamicTypeWrapper.SetupGhosts and VMClassLoader.findLoadedClass)
2005-06-01 13:49:30 +04:00
internal TypeWrapper GetLoadedClass ( string name )
2004-08-17 13:05:21 +04:00
{
2005-06-01 13:49:30 +04:00
lock ( types . SyncRoot )
{
return ( TypeWrapper ) types [ name ] ;
}
2004-08-17 13:05:21 +04:00
}
2003-12-20 01:19:18 +03:00
2006-05-15 13:08:01 +04:00
private TypeWrapper RegisterInitiatingLoader ( TypeWrapper tw )
2005-07-27 19:57:55 +04:00
{
2005-08-25 17:15:42 +04:00
if ( tw = = null | | tw . IsUnloadable | | tw . IsPrimitive )
2005-07-27 19:57:55 +04:00
return tw ;
lock ( types . SyncRoot )
{
object existing = types [ tw . Name ] ;
if ( existing ! = tw )
{
if ( existing ! = null )
{
throw new LinkageError ( "duplicate class definition: " + tw . Name ) ;
}
if ( tw . IsArray )
{
TypeWrapper elem = tw ;
// TODO there should be a way to get the ultimate element type
// without creating all the intermediate types
while ( elem . IsArray )
{
elem = elem . ElementTypeWrapper ;
}
2006-05-15 13:08:01 +04:00
// HACK elem.ElementTypeWrapper as an evil side effect registers the initiating loader
// so if we're the same loader, don't do it again
if ( ! elem . IsPrimitive & & ! types . ContainsKey ( elem . Name ) )
{
RegisterInitiatingLoader ( elem ) ;
}
2005-07-27 19:57:55 +04:00
}
// NOTE if types.ContainsKey(tw.Name) is true (i.e. the value is null),
// we currently have a DefineClass in progress on another thread and we've
// beaten that thread to the punch by loading the class from a parent class
// loader instead. This is ok as DefineClass will throw a LinkageError when
// it is done.
types [ tw . Name ] = tw ;
}
}
return tw ;
}
2005-12-07 12:06:32 +03:00
#if ! COMPACT_FRAMEWORK
2006-03-11 21:35:29 +03:00
// HACK the proxyClassLoader is used to dynamically load classes in the boot class loader
// (e.g. when a Proxy is defined a boot class)
private static DynamicClassLoader proxyClassLoader ;
2006-02-22 17:44:07 +03:00
internal virtual TypeWrapper DefineClass ( ClassFile f , object protectionDomain )
2003-06-10 17:28:47 +04:00
{
2006-03-11 21:35:29 +03:00
lock ( wrapperLock )
{
if ( proxyClassLoader = = null )
{
proxyClassLoader = new DynamicClassLoader ( null ) ;
}
}
return proxyClassLoader . DefineClass ( f , protectionDomain ) ;
2006-02-22 17:44:07 +03:00
}
internal TypeWrapper DefineNetExpType ( string name , string assemblyName )
{
Debug . Assert ( this = = GetBootstrapClassLoader ( ) ) ;
TypeWrapper type ;
lock ( types . SyncRoot )
2003-06-10 17:28:47 +04:00
{
2006-02-22 17:44:07 +03:00
// we need to check if we've already got it, because other classloaders than the bootstrap classloader may
// "define" NetExp types, there is a potential race condition if multiple classloaders try to define the
// same type simultaneously.
type = ( TypeWrapper ) types [ name ] ;
if ( type ! = null )
2003-06-10 17:28:47 +04:00
{
2006-02-22 17:44:07 +03:00
return type ;
}
}
// The sole purpose of the netexp class is to let us load the assembly that the class lives in,
// once we've done that, all types in it become visible.
Assembly asm ;
try
{
asm = Assembly . Load ( assemblyName ) ;
}
catch ( Exception x )
{
throw new NoClassDefFoundError ( name + " (" + x . Message + ")" ) ;
}
// pre-compiled Java types can also live in a netexp referenced assembly,
// so we have to explicitly check for those
// (DotNetTypeWrapper.CreateDotNetTypeWrapper will refuse to return Java types).
Type t = GetJavaTypeFromAssembly ( asm , name ) ;
if ( t ! = null )
{
return GetWrapperFromBootstrapType ( t ) ;
}
type = DotNetTypeWrapper . CreateDotNetTypeWrapper ( name ) ;
if ( type = = null )
{
throw new NoClassDefFoundError ( name + " not found in " + assemblyName ) ;
}
lock ( types . SyncRoot )
{
TypeWrapper race = ( TypeWrapper ) types [ name ] ;
if ( race = = null )
{
types . Add ( name , type ) ;
2005-06-01 13:49:30 +04:00
}
else
{
2006-02-22 17:44:07 +03:00
type = race ;
2003-06-10 17:28:47 +04:00
}
}
2006-02-22 17:44:07 +03:00
return type ;
2003-06-10 17:28:47 +04:00
}
2005-12-07 12:06:32 +03:00
#endif
2003-06-10 17:28:47 +04:00
2005-06-01 13:49:30 +04:00
internal TypeWrapper LoadClassByDottedName ( string name )
2003-03-17 17:02:46 +03:00
{
2005-08-25 11:46:57 +04:00
TypeWrapper type = LoadClassByDottedNameFast ( name , true ) ;
2005-06-01 13:49:30 +04:00
if ( type ! = null )
{
return type ;
}
throw new ClassNotFoundException ( name ) ;
2003-03-17 17:02:46 +03:00
}
2005-06-01 13:49:30 +04:00
internal TypeWrapper LoadClassByDottedNameFast ( string name )
2005-08-25 11:46:57 +04:00
{
return LoadClassByDottedNameFast ( name , false ) ;
}
private TypeWrapper LoadClassByDottedNameFast ( string name , bool throwClassNotFoundException )
2003-02-15 12:20:26 +03:00
{
2005-06-01 13:49:30 +04:00
// .NET 1.1 has a limit of 1024 characters for type names
2006-05-15 13:08:01 +04:00
if ( name . Length > = 1024 | | name . Length = = 0 )
2002-12-18 19:00:25 +03:00
{
2005-06-01 13:49:30 +04:00
return null ;
2002-12-18 19:00:25 +03:00
}
2005-06-01 13:49:30 +04:00
Profiler . Enter ( "LoadClassByDottedName" ) ;
try
2002-12-18 19:00:25 +03:00
{
2005-06-01 13:49:30 +04:00
TypeWrapper type ;
lock ( types . SyncRoot )
2002-12-18 19:00:25 +03:00
{
2005-06-01 13:49:30 +04:00
type = ( TypeWrapper ) types [ name ] ;
if ( type = = null & & types . ContainsKey ( name ) )
2004-12-03 10:57:15 +03:00
{
2005-06-01 13:49:30 +04:00
// NOTE this can also happen if we (incorrectly) trigger a load of this class during
// the loading of the base class, so we print a trace message here.
Tracer . Error ( Tracer . ClassLoading , "**** ClassCircularityError: {0} ****" , name ) ;
throw new ClassCircularityError ( name ) ;
2004-12-03 10:57:15 +03:00
}
}
2005-06-01 13:49:30 +04:00
if ( type ! = null )
2004-12-03 10:57:15 +03:00
{
2005-06-01 13:49:30 +04:00
return type ;
2004-12-03 10:57:15 +03:00
}
2005-06-01 13:49:30 +04:00
if ( name . Length > 1 & & name [ 0 ] = = '[' )
2004-12-03 10:57:15 +03:00
{
2005-06-01 13:49:30 +04:00
int dims = 1 ;
while ( name [ dims ] = = '[' )
2003-08-26 15:24:17 +04:00
{
2005-06-01 13:49:30 +04:00
dims + + ;
2003-08-26 15:24:17 +04:00
}
2005-06-01 13:49:30 +04:00
if ( name [ dims ] = = 'L' )
2002-12-29 19:27:00 +03:00
{
2005-06-01 13:49:30 +04:00
if ( ! name . EndsWith ( ";" ) | | name . Length < = dims + 2 | | name [ dims + 1 ] = = '[' )
2003-08-21 14:06:34 +04:00
{
2005-06-01 13:49:30 +04:00
// malformed class name
return null ;
2003-08-21 14:06:34 +04:00
}
2005-06-01 13:49:30 +04:00
string elemClass = name . Substring ( dims + 1 , name . Length - dims - 2 ) ;
type = LoadClassByDottedNameFast ( elemClass ) ;
if ( type ! = null )
2003-08-21 14:06:34 +04:00
{
2005-12-07 12:06:32 +03:00
#if ! COMPACT_FRAMEWORK
2005-11-01 17:01:42 +03:00
// HACK make sure we don't go through a user class loader when creating
// an array for a precompiled or .NET type
2006-03-23 14:57:41 +03:00
// (this is to compensate for the hack that returns the system class loader
// for precompiled classes or .NET types)
2005-11-01 17:01:42 +03:00
if ( type is DynamicTypeWrapper )
{
type = type . GetClassLoader ( ) . CreateArrayType ( name , type , dims ) ;
}
else
2005-12-07 12:06:32 +03:00
#endif
2005-11-01 17:01:42 +03:00
{
type = GetBootstrapClassLoader ( ) . CreateArrayType ( name , type , dims ) ;
}
2003-08-21 14:06:34 +04:00
}
2005-07-27 19:57:55 +04:00
return RegisterInitiatingLoader ( type ) ;
2002-12-29 19:27:00 +03:00
}
2005-06-01 13:49:30 +04:00
if ( name . Length ! = dims + 1 )
{
// malformed class name
return null ;
}
switch ( name [ dims ] )
2003-08-21 14:06:34 +04:00
{
2005-06-01 13:49:30 +04:00
case 'B' :
2005-07-27 19:57:55 +04:00
return RegisterInitiatingLoader ( GetBootstrapClassLoader ( ) . CreateArrayType ( name , PrimitiveTypeWrapper . BYTE , dims ) ) ;
2005-06-01 13:49:30 +04:00
case 'C' :
2005-07-27 19:57:55 +04:00
return RegisterInitiatingLoader ( GetBootstrapClassLoader ( ) . CreateArrayType ( name , PrimitiveTypeWrapper . CHAR , dims ) ) ;
2005-06-01 13:49:30 +04:00
case 'D' :
2005-07-27 19:57:55 +04:00
return RegisterInitiatingLoader ( GetBootstrapClassLoader ( ) . CreateArrayType ( name , PrimitiveTypeWrapper . DOUBLE , dims ) ) ;
2005-06-01 13:49:30 +04:00
case 'F' :
2005-07-27 19:57:55 +04:00
return RegisterInitiatingLoader ( GetBootstrapClassLoader ( ) . CreateArrayType ( name , PrimitiveTypeWrapper . FLOAT , dims ) ) ;
2005-06-01 13:49:30 +04:00
case 'I' :
2005-07-27 19:57:55 +04:00
return RegisterInitiatingLoader ( GetBootstrapClassLoader ( ) . CreateArrayType ( name , PrimitiveTypeWrapper . INT , dims ) ) ;
2005-06-01 13:49:30 +04:00
case 'J' :
2005-07-27 19:57:55 +04:00
return RegisterInitiatingLoader ( GetBootstrapClassLoader ( ) . CreateArrayType ( name , PrimitiveTypeWrapper . LONG , dims ) ) ;
2005-06-01 13:49:30 +04:00
case 'S' :
2005-07-27 19:57:55 +04:00
return RegisterInitiatingLoader ( GetBootstrapClassLoader ( ) . CreateArrayType ( name , PrimitiveTypeWrapper . SHORT , dims ) ) ;
2005-06-01 13:49:30 +04:00
case 'Z' :
2005-07-27 19:57:55 +04:00
return RegisterInitiatingLoader ( GetBootstrapClassLoader ( ) . CreateArrayType ( name , PrimitiveTypeWrapper . BOOLEAN , dims ) ) ;
2005-06-01 13:49:30 +04:00
default :
return null ;
2003-08-21 14:06:34 +04:00
}
2005-06-01 13:49:30 +04:00
}
if ( this = = GetBootstrapClassLoader ( ) )
{
2006-05-15 13:08:01 +04:00
Type t = GetBootstrapTypeRaw ( name ) ;
if ( t ! = null )
2003-08-21 14:06:34 +04:00
{
2006-05-15 13:08:01 +04:00
return RegisterInitiatingLoader ( GetWrapperFromBootstrapType ( t ) ) ;
}
type = DotNetTypeWrapper . CreateDotNetTypeWrapper ( name ) ;
if ( type ! = null )
{
Debug . Assert ( type . Name = = name , type . Name + " != " + name ) ;
lock ( types . SyncRoot )
2005-06-01 13:49:30 +04:00
{
2006-05-15 13:08:01 +04:00
// another thread may have beaten us to it and in that
// case we don't want to overwrite the previous one
TypeWrapper race = ( TypeWrapper ) types [ name ] ;
if ( race = = null )
2005-06-01 13:49:30 +04:00
{
2006-05-15 13:08:01 +04:00
types [ name ] = type ;
2004-08-17 13:05:21 +04:00
}
else
{
2006-05-15 13:08:01 +04:00
type = race ;
2004-08-17 13:05:21 +04:00
}
}
2006-05-15 13:08:01 +04:00
return type ;
2003-08-21 14:06:34 +04:00
}
2006-05-15 13:08:01 +04:00
#if STATIC_COMPILER
// NOTE it is important that this is done last, because otherwise we will
// load the netexp generated fake types (e.g. delegate inner interface) instead
// of having DotNetTypeWrapper generating it.
type = GetTypeWrapperCompilerHook ( name ) ;
if ( type ! = null )
2003-08-21 14:06:34 +04:00
{
2006-05-15 13:08:01 +04:00
return type ;
2005-06-01 13:49:30 +04:00
}
2006-05-15 13:08:01 +04:00
#endif // STATIC_COMPILER
2005-06-01 13:49:30 +04:00
if ( javaClassLoader = = null )
{
return null ;
2003-08-21 14:06:34 +04:00
}
2002-12-29 19:27:00 +03:00
}
2006-03-11 21:35:29 +03:00
#if ! COMPACT_FRAMEWORK
2006-05-15 13:08:01 +04:00
// if we're here, we're not the bootstrap class loader and don't have a java class loader,
// that must mean that we're either the proxyClassLoader or a ReflectionOnly class loader
// and we should delegate to the bootstrap class loader
if ( javaClassLoader = = null )
2006-03-11 21:35:29 +03:00
{
return GetBootstrapClassLoader ( ) . LoadClassByDottedNameFast ( name , throwClassNotFoundException ) ;
}
#endif
2006-04-10 13:09:09 +04:00
#if ! STATIC_COMPILER
2005-06-01 13:49:30 +04:00
// NOTE just like Java does (I think), we take the classloader lock before calling the loadClass method
lock ( javaClassLoader )
2002-12-29 19:27:00 +03:00
{
2005-06-01 13:49:30 +04:00
Profiler . Enter ( "ClassLoader.loadClass" ) ;
try
{
type = ( TypeWrapper ) JVM . Library . loadClass ( javaClassLoader , name ) ;
}
2005-08-24 15:35:00 +04:00
catch ( Exception x )
{
2005-08-25 11:46:57 +04:00
if ( ! throwClassNotFoundException
& & LoadClassCritical ( "java.lang.ClassNotFoundException" ) . TypeAsBaseType . IsInstanceOfType ( x ) )
{
return null ;
}
2005-08-24 15:35:00 +04:00
throw new ClassLoadingException ( IKVM . Runtime . Util . MapException ( x ) ) ;
}
2005-06-01 13:49:30 +04:00
finally
{
Profiler . Leave ( "ClassLoader.loadClass" ) ;
}
2005-08-01 14:27:06 +04:00
// NOTE to be safe, we register the initiating loader,
// while we're holding the lock on the class loader object
return RegisterInitiatingLoader ( type ) ;
2002-12-29 19:27:00 +03:00
}
2006-04-10 13:09:09 +04:00
#else
return null ;
#endif
2005-06-01 13:49:30 +04:00
}
finally
{
Profiler . Leave ( "LoadClassByDottedName" ) ;
2002-12-18 19:00:25 +03:00
}
}
2005-06-01 13:49:30 +04:00
private TypeWrapper GetWrapperFromBootstrapType ( Type type )
2005-01-03 11:26:21 +03:00
{
2005-06-01 13:49:30 +04:00
//Tracer.Info(Tracer.Runtime, "GetWrapperFromBootstrapType: {0}", type.FullName);
Debug . Assert ( ! type . IsArray , "!type.IsArray" , type . FullName ) ;
2005-12-07 12:06:32 +03:00
#if ! COMPACT_FRAMEWORK
2005-06-01 13:49:30 +04:00
Debug . Assert ( ! ( type . Assembly is AssemblyBuilder ) , "!(type.Assembly is AssemblyBuilder)" , type . FullName ) ;
2005-12-07 12:06:32 +03:00
#endif
2005-06-01 13:49:30 +04:00
// only the bootstrap classloader can own compiled types
Debug . Assert ( this = = GetBootstrapClassLoader ( ) , "this == GetBootstrapClassLoader()" , type . FullName ) ;
2005-12-07 12:06:32 +03:00
bool javaType = AttributeHelper . IsJavaModule ( type . Module ) ;
2005-06-01 13:49:30 +04:00
string name ;
2005-01-03 11:26:21 +03:00
if ( javaType )
{
2005-06-01 13:49:30 +04:00
name = CompiledTypeWrapper . GetName ( type ) ;
2005-01-03 11:26:21 +03:00
}
else
{
2005-06-01 13:49:30 +04:00
name = DotNetTypeWrapper . GetName ( type ) ;
2005-01-03 11:26:21 +03:00
}
2005-06-01 13:49:30 +04:00
TypeWrapper wrapper ;
2004-08-17 13:05:21 +04:00
lock ( types . SyncRoot )
2003-08-13 19:00:41 +04:00
{
2005-06-01 13:49:30 +04:00
wrapper = ( TypeWrapper ) types [ name ] ;
}
2005-08-02 12:44:55 +04:00
if ( wrapper ! = null )
{
if ( wrapper . TypeAsTBD ! = type )
{
2006-05-15 13:08:01 +04:00
string msg = String . Format ( "\nTypename \"{0}\" is imported from multiple assemblies:\n{1}\n{2}\n" , type . FullName , wrapper . TypeAsTBD . Assembly . FullName , type . Assembly . FullName ) ;
2005-08-02 12:44:55 +04:00
JVM . CriticalFailure ( msg , null ) ;
}
}
else
2005-06-01 13:49:30 +04:00
{
if ( javaType )
2004-08-17 13:05:21 +04:00
{
2005-06-01 13:49:30 +04:00
// since this type was compiled from Java source, we have to look for our
// attributes
wrapper = CompiledTypeWrapper . newInstance ( name , type ) ;
2004-08-17 13:05:21 +04:00
}
2005-01-03 11:26:21 +03:00
else
{
2006-05-15 13:08:01 +04:00
if ( ! DotNetTypeWrapper . IsAllowedOutside ( type ) )
{
return null ;
}
2005-06-01 13:49:30 +04:00
// since this type was not compiled from Java source, we don't need to
// look for our attributes, but we do need to filter unrepresentable
// stuff (and transform some other stuff)
wrapper = new DotNetTypeWrapper ( type ) ;
}
Debug . Assert ( wrapper . Name = = name , "wrapper.Name == name" , type . FullName ) ;
lock ( types . SyncRoot )
{
// another thread may have beaten us to it and in that
// case we don't want to overwrite the previous one
TypeWrapper race = ( TypeWrapper ) types [ name ] ;
if ( race = = null )
{
types . Add ( name , wrapper ) ;
typeToTypeWrapper . Add ( type , wrapper ) ;
}
else
{
wrapper = race ;
}
2005-01-03 11:26:21 +03:00
}
2003-08-13 19:00:41 +04:00
}
2005-06-01 13:49:30 +04:00
return wrapper ;
2003-08-13 19:00:41 +04:00
}
2002-12-18 19:00:25 +03:00
2005-06-01 13:49:30 +04:00
// NOTE this method only sees pre-compiled Java classes
2006-05-15 13:08:01 +04:00
private Type GetBootstrapTypeRaw ( string name )
2002-12-18 19:00:25 +03:00
{
2005-12-07 12:06:32 +03:00
#if COMPACT_FRAMEWORK
// TODO figure this out
return GetJavaTypeFromAssembly ( JVM . CoreAssembly , name ) ;
#else
Assembly [ ] assemblies ;
#if WHIDBEY
2006-05-15 13:08:01 +04:00
if ( JVM . IsStaticCompiler )
2005-12-07 12:06:32 +03:00
{
assemblies = AppDomain . CurrentDomain . ReflectionOnlyGetAssemblies ( ) ;
}
else
{
assemblies = AppDomain . CurrentDomain . GetAssemblies ( ) ;
}
#else
assemblies = AppDomain . CurrentDomain . GetAssemblies ( ) ;
#endif
foreach ( Assembly a in assemblies )
2003-02-20 17:18:38 +03:00
{
2005-06-01 13:49:30 +04:00
if ( ! ( a is AssemblyBuilder ) )
2004-01-11 16:14:42 +03:00
{
2005-06-01 13:49:30 +04:00
Type t = GetJavaTypeFromAssembly ( a , name ) ;
if ( t ! = null )
{
return t ;
}
2004-01-11 16:14:42 +03:00
}
2003-02-20 17:18:38 +03:00
}
2005-06-01 13:49:30 +04:00
return null ;
2005-12-07 12:06:32 +03:00
#endif
2002-12-18 19:00:25 +03:00
}
2005-06-01 13:49:30 +04:00
private static Type GetJavaTypeFromAssembly ( Assembly a , string name )
2004-11-16 14:11:53 +03:00
{
2005-06-27 13:06:57 +04:00
try
2005-06-01 13:49:30 +04:00
{
2005-06-27 13:06:57 +04:00
Type t = a . GetType ( name ) ;
2005-08-25 13:36:36 +04:00
if ( t ! = null
2005-12-07 12:06:32 +03:00
& & AttributeHelper . IsJavaModule ( t . Module )
2006-05-15 13:08:01 +04:00
& & ! AttributeHelper . IsHideFromJava ( t )
& & ! t . IsArray
& & ! t . IsPointer
& & ! t . IsByRef )
2005-06-27 13:06:57 +04:00
{
return t ;
}
// HACK we might be looking for an inner classes
t = a . GetType ( name . Replace ( '$' , '+' ) ) ;
2005-08-25 13:36:36 +04:00
if ( t ! = null
2005-12-07 12:06:32 +03:00
& & AttributeHelper . IsJavaModule ( t . Module )
2006-05-15 13:08:01 +04:00
& & ! AttributeHelper . IsHideFromJava ( t )
& & ! t . IsArray
& & ! t . IsPointer
& & ! t . IsByRef )
2005-06-27 13:06:57 +04:00
{
return t ;
}
2005-06-01 13:49:30 +04:00
}
2005-06-27 13:06:57 +04:00
catch ( ArgumentException x )
2005-06-01 13:49:30 +04:00
{
2005-06-27 13:06:57 +04:00
// we can end up here because we replace the $ with a plus sign
// (or client code did a Class.forName() on an invalid name)
Tracer . Info ( Tracer . Runtime , x . Message ) ;
2005-06-01 13:49:30 +04:00
}
2006-05-23 16:49:16 +04:00
catch ( FileLoadException x )
{
// this can only happen if the assembly was loaded in the ReflectionOnly
// context and the requested type references a type in another assembly
// that cannot be found in the ReflectionOnly context
// TODO figure out what other exceptions Assembly.GetType() can throw
Tracer . Info ( Tracer . Runtime , x . Message ) ;
}
2005-06-01 13:49:30 +04:00
return null ;
2004-11-16 14:11:53 +03:00
}
2002-12-18 19:00:25 +03:00
2006-05-15 13:08:01 +04:00
#if STATIC_COMPILER
2005-06-01 13:49:30 +04:00
internal virtual TypeWrapper GetTypeWrapperCompilerHook ( string name )
2002-12-18 19:00:25 +03:00
{
2005-06-01 13:49:30 +04:00
return null ;
2005-01-03 11:26:21 +03:00
}
2006-05-15 13:08:01 +04:00
#endif // STATIC_COMPILER
2005-06-01 13:49:30 +04:00
// NOTE this method can actually return null if the resulting array type name would be too long
// for .NET to handle.
private TypeWrapper CreateArrayType ( string name , TypeWrapper elementTypeWrapper , int dims )
2005-01-03 11:26:21 +03:00
{
2005-06-01 13:49:30 +04:00
Debug . Assert ( new String ( '[' , dims ) + elementTypeWrapper . SigName = = name ) ;
Debug . Assert ( ! elementTypeWrapper . IsUnloadable & & ! elementTypeWrapper . IsVerifierType & & ! elementTypeWrapper . IsArray ) ;
Debug . Assert ( dims > = 1 ) ;
Type elementType = elementTypeWrapper . TypeAsArrayType ;
TypeWrapper wrapper ;
lock ( types . SyncRoot )
2005-01-03 11:26:21 +03:00
{
2005-06-01 13:49:30 +04:00
wrapper = ( TypeWrapper ) types [ name ] ;
2005-01-03 11:26:21 +03:00
}
2005-06-01 13:49:30 +04:00
if ( wrapper = = null )
2005-01-03 11:26:21 +03:00
{
2005-06-01 13:49:30 +04:00
String netname = elementType . FullName + "[]" ;
for ( int i = 1 ; i < dims ; i + + )
2002-12-18 19:00:25 +03:00
{
2005-06-01 13:49:30 +04:00
netname + = "[]" ;
}
// .NET 1.1 has a limit of 1024 characters for type names
if ( netname . Length > = 1024 )
{
return null ;
}
Type array ;
2005-12-07 12:06:32 +03:00
#if ! COMPACT_FRAMEWORK
2005-06-01 13:49:30 +04:00
if ( elementType . Module is ModuleBuilder )
{
// FXBUG ModuleBuilder.GetType() is broken (I think), it fires a TypeResolveEvent when
// you try to construct an array type from an unfinished type. I don't think it should
// do that. We have to work around that by setting a global flag (yuck) to prevent us
// from responding to the TypeResolveEvent.
lock ( arrayConstructionLock )
{
arrayConstructionHack = true ;
try
{
array = ( ( ModuleBuilder ) elementType . Module ) . GetType ( netname ) ;
}
finally
{
arrayConstructionHack = false ;
}
}
}
else
2005-12-07 12:06:32 +03:00
#endif
2005-06-01 13:49:30 +04:00
{
array = elementType . Assembly . GetType ( netname , true ) ;
}
Modifiers modifiers = Modifiers . Final | Modifiers . Abstract ;
Modifiers reflectiveModifiers = modifiers ;
modifiers | = elementTypeWrapper . Modifiers & Modifiers . Public ;
reflectiveModifiers | = elementTypeWrapper . ReflectiveModifiers & Modifiers . AccessMask ;
wrapper = new ArrayTypeWrapper ( array , modifiers , reflectiveModifiers , name , this ) ;
lock ( types . SyncRoot )
{
// another thread may have beaten us to it and in that
// case we don't want to overwrite the previous one
TypeWrapper race = ( TypeWrapper ) types [ name ] ;
if ( race = = null )
2005-01-03 11:26:21 +03:00
{
2005-06-01 13:49:30 +04:00
types . Add ( name , wrapper ) ;
2005-12-07 12:06:32 +03:00
#if COMPACT_FRAMEWORK
if ( ! wrapper . IsGhostArray )
{
Debug . Assert ( ! typeToTypeWrapper . ContainsKey ( array ) , name ) ;
typeToTypeWrapper . Add ( array , wrapper ) ;
}
#else
2005-06-01 13:49:30 +04:00
if ( ! ( elementType is TypeBuilder ) & & ! wrapper . IsGhostArray )
{
Debug . Assert ( ! typeToTypeWrapper . ContainsKey ( array ) , name ) ;
typeToTypeWrapper . Add ( array , wrapper ) ;
}
2005-12-07 12:06:32 +03:00
#endif
2005-01-03 11:26:21 +03:00
}
2005-06-01 13:49:30 +04:00
else
2005-01-03 11:26:21 +03:00
{
2005-06-01 13:49:30 +04:00
wrapper = race ;
2005-01-03 11:26:21 +03:00
}
2002-12-18 19:00:25 +03:00
}
2005-01-03 11:26:21 +03:00
}
2005-06-01 13:49:30 +04:00
return wrapper ;
}
internal object GetJavaClassLoader ( )
2003-12-20 01:19:18 +03:00
{
2005-06-01 13:49:30 +04:00
return ( this = = GetBootstrapClassLoader ( ) ) ? null : javaClassLoader ;
2005-01-03 11:26:21 +03:00
}
2005-06-01 13:49:30 +04:00
// When -Xbootclasspath is specified, we use a URLClassLoader as an
// additional bootstrap class loader (this is not visible to the Java code).
// We need to access this to be able to load resources.
internal static object GetJavaBootstrapClassLoader ( )
2005-01-03 11:26:21 +03:00
{
2005-06-01 13:49:30 +04:00
return GetBootstrapClassLoader ( ) . javaClassLoader ;
2005-01-03 11:26:21 +03:00
}
2005-06-01 13:49:30 +04:00
internal TypeWrapper ExpressionTypeWrapper ( string type )
2002-12-18 19:00:25 +03:00
{
2005-06-01 13:49:30 +04:00
Debug . Assert ( ! type . StartsWith ( "Lret;" ) ) ;
Debug . Assert ( type ! = "Lnull" ) ;
int index = 0 ;
return SigDecoderWrapper ( ref index , type ) ;
2002-12-18 19:00:25 +03:00
}
2005-06-01 13:49:30 +04:00
// NOTE this exposes potentially unfinished types
internal Type [ ] ArgTypeListFromSig ( string sig )
2002-12-18 19:00:25 +03:00
{
2005-06-01 13:49:30 +04:00
if ( sig [ 1 ] = = ')' )
{
2005-12-07 12:06:32 +03:00
#if COMPACT_FRAMEWORK
return new Type [ 0 ] ;
#else
2005-06-01 13:49:30 +04:00
return Type . EmptyTypes ;
2005-12-07 12:06:32 +03:00
#endif
2005-06-01 13:49:30 +04:00
}
TypeWrapper [ ] wrappers = ArgTypeWrapperListFromSig ( sig ) ;
Type [ ] types = new Type [ wrappers . Length ] ;
for ( int i = 0 ; i < wrappers . Length ; i + + )
2002-12-18 19:00:25 +03:00
{
2005-06-01 13:49:30 +04:00
types [ i ] = wrappers [ i ] . TypeAsSignatureType ;
2002-12-18 19:00:25 +03:00
}
2005-06-01 13:49:30 +04:00
return types ;
}
// NOTE: this will ignore anything following the sig marker (so that it can be used to decode method signatures)
private TypeWrapper SigDecoderWrapper ( ref int index , string sig )
{
switch ( sig [ index + + ] )
2002-12-18 19:00:25 +03:00
{
2005-06-01 13:49:30 +04:00
case 'B' :
return PrimitiveTypeWrapper . BYTE ;
case 'C' :
return PrimitiveTypeWrapper . CHAR ;
case 'D' :
return PrimitiveTypeWrapper . DOUBLE ;
case 'F' :
return PrimitiveTypeWrapper . FLOAT ;
case 'I' :
return PrimitiveTypeWrapper . INT ;
case 'J' :
return PrimitiveTypeWrapper . LONG ;
case 'L' :
2002-12-18 19:00:25 +03:00
{
2005-06-01 13:49:30 +04:00
int pos = index ;
index = sig . IndexOf ( ';' , index ) + 1 ;
return LoadClassByDottedName ( sig . Substring ( pos , index - pos - 1 ) ) ;
2002-12-18 19:00:25 +03:00
}
2005-06-01 13:49:30 +04:00
case 'S' :
return PrimitiveTypeWrapper . SHORT ;
case 'Z' :
return PrimitiveTypeWrapper . BOOLEAN ;
case 'V' :
return PrimitiveTypeWrapper . VOID ;
case '[' :
2002-12-18 19:00:25 +03:00
{
2005-06-01 13:49:30 +04:00
// TODO this can be optimized
string array = "[" ;
while ( sig [ index ] = = '[' )
2002-12-18 19:00:25 +03:00
{
2005-06-01 13:49:30 +04:00
index + + ;
array + = "[" ;
}
switch ( sig [ index ] )
{
case 'L' :
{
int pos = index ;
index = sig . IndexOf ( ';' , index ) + 1 ;
return LoadClassByDottedName ( array + sig . Substring ( pos , index - pos ) ) ;
}
case 'B' :
case 'C' :
case 'D' :
case 'F' :
case 'I' :
case 'J' :
case 'S' :
case 'Z' :
return LoadClassByDottedName ( array + sig [ index + + ] ) ;
default :
throw new InvalidOperationException ( sig . Substring ( index ) ) ;
2002-12-18 19:00:25 +03:00
}
}
2005-06-01 13:49:30 +04:00
default :
throw new InvalidOperationException ( sig . Substring ( index ) ) ;
2002-12-18 19:00:25 +03:00
}
}
2004-03-16 20:10:09 +03:00
2005-06-01 13:49:30 +04:00
internal TypeWrapper FieldTypeWrapperFromSig ( string sig )
2002-12-18 19:00:25 +03:00
{
2005-06-01 13:49:30 +04:00
int index = 0 ;
return SigDecoderWrapper ( ref index , sig ) ;
2002-12-18 19:00:25 +03:00
}
2005-06-01 13:49:30 +04:00
internal TypeWrapper RetTypeWrapperFromSig ( string sig )
2002-12-18 19:00:25 +03:00
{
2005-06-01 13:49:30 +04:00
int index = sig . IndexOf ( ')' ) + 1 ;
return SigDecoderWrapper ( ref index , sig ) ;
2002-12-18 19:00:25 +03:00
}
2005-06-01 13:49:30 +04:00
internal TypeWrapper [ ] ArgTypeWrapperListFromSig ( string sig )
2002-12-18 19:00:25 +03:00
{
2005-06-01 13:49:30 +04:00
if ( sig [ 1 ] = = ')' )
{
return TypeWrapper . EmptyArray ;
}
ArrayList list = new ArrayList ( ) ;
for ( int i = 1 ; sig [ i ] ! = ')' ; )
2004-08-17 13:05:21 +04:00
{
2005-06-01 13:49:30 +04:00
list . Add ( SigDecoderWrapper ( ref i , sig ) ) ;
2004-08-17 13:05:21 +04:00
}
2005-06-01 13:49:30 +04:00
TypeWrapper [ ] types = new TypeWrapper [ list . Count ] ;
list . CopyTo ( types ) ;
return types ;
2002-12-18 19:00:25 +03:00
}
2004-09-09 15:17:55 +04:00
2005-06-01 13:49:30 +04:00
internal static ClassLoaderWrapper GetBootstrapClassLoader ( )
2004-10-04 23:30:53 +04:00
{
2006-03-23 14:57:41 +03:00
lock ( wrapperLock )
2005-06-01 13:49:30 +04:00
{
if ( bootstrapClassLoader = = null )
{
2006-02-22 17:44:07 +03:00
bootstrapClassLoader = new BootstrapClassLoader ( ) ;
2005-06-01 13:49:30 +04:00
}
return bootstrapClassLoader ;
}
2004-10-04 23:30:53 +04:00
}
2005-06-01 13:49:30 +04:00
internal static ClassLoaderWrapper GetSystemClassLoader ( )
2004-09-09 15:17:55 +04:00
{
2006-04-10 13:09:09 +04:00
#if STATIC_COMPILER
2005-06-01 13:49:30 +04:00
// during static compilation, we don't have a system class loader
2006-04-10 13:09:09 +04:00
return GetBootstrapClassLoader ( ) ;
#else
2005-06-01 13:49:30 +04:00
if ( systemClassLoader = = null )
{
systemClassLoader = GetClassLoaderWrapper ( JVM . Library . getSystemClassLoader ( ) ) ;
}
return systemClassLoader ;
2006-04-10 13:09:09 +04:00
#endif
2004-09-09 15:17:55 +04:00
}
2006-04-10 13:09:09 +04:00
#if ! STATIC_COMPILER
2005-06-01 13:49:30 +04:00
internal static ClassLoaderWrapper GetClassLoaderWrapper ( object javaClassLoader )
2002-12-18 19:00:25 +03:00
{
2005-06-01 13:49:30 +04:00
if ( javaClassLoader = = null | | GetBootstrapClassLoader ( ) . javaClassLoader = = javaClassLoader )
2004-08-17 13:05:21 +04:00
{
2005-06-01 13:49:30 +04:00
return GetBootstrapClassLoader ( ) ;
}
2005-09-06 12:06:04 +04:00
lock ( wrapperLock )
2005-06-01 13:49:30 +04:00
{
2005-09-06 12:06:04 +04:00
ClassLoaderWrapper wrapper = ( ClassLoaderWrapper ) JVM . Library . getWrapperFromClassLoader ( javaClassLoader ) ;
2005-06-01 13:49:30 +04:00
if ( wrapper = = null )
{
2006-02-22 17:44:07 +03:00
wrapper = new DynamicClassLoader ( javaClassLoader ) ;
2005-09-06 12:06:04 +04:00
JVM . Library . setWrapperForClassLoader ( javaClassLoader , wrapper ) ;
2005-06-01 13:49:30 +04:00
}
return wrapper ;
2004-08-17 13:05:21 +04:00
}
2002-12-18 19:00:25 +03:00
}
2006-04-10 13:09:09 +04:00
#endif
2002-12-18 19:00:25 +03:00
2005-06-01 13:49:30 +04:00
// This only returns the wrapper for a Type if that wrapper has already been created, otherwise
// it returns null
// If the wrapper doesn't exist, that means that the type is either a .NET type or a pre-compiled Java class
2006-05-23 16:49:16 +04:00
private static TypeWrapper GetWrapperFromTypeFast ( Type type )
2002-12-18 19:00:25 +03:00
{
2005-06-01 13:49:30 +04:00
TypeWrapper . AssertFinished ( type ) ;
2006-01-23 13:18:44 +03:00
Debug . Assert ( ! Whidbey . ContainsGenericParameters ( type ) ) ;
2005-06-01 13:49:30 +04:00
TypeWrapper wrapper = ( TypeWrapper ) typeToTypeWrapper [ type ] ;
if ( wrapper = = null )
2003-02-15 21:52:32 +03:00
{
2005-06-01 13:49:30 +04:00
string name = ( string ) remappedTypes [ type ] ;
if ( name ! = null )
{
return LoadClassCritical ( name ) ;
}
2003-02-15 21:52:32 +03:00
}
2005-06-01 13:49:30 +04:00
return wrapper ;
2003-02-15 21:52:32 +03:00
}
2005-06-01 13:49:30 +04:00
internal static TypeWrapper GetWrapperFromType ( Type type )
2003-02-15 21:52:32 +03:00
{
2005-06-01 13:49:30 +04:00
//Tracer.Info(Tracer.Runtime, "GetWrapperFromType: {0}", type.AssemblyQualifiedName);
TypeWrapper . AssertFinished ( type ) ;
2006-01-23 13:18:44 +03:00
Debug . Assert ( ! Whidbey . ContainsGenericParameters ( type ) ) ;
2005-06-01 13:49:30 +04:00
TypeWrapper wrapper = GetWrapperFromTypeFast ( type ) ;
if ( wrapper = = null )
2003-02-17 13:13:16 +03:00
{
2005-06-01 13:49:30 +04:00
Debug . Assert ( type ! = typeof ( object ) & & type ! = typeof ( string ) ) ;
if ( type . IsArray )
2003-02-17 13:13:16 +03:00
{
2005-06-01 13:49:30 +04:00
// it might be an array of a dynamically compiled Java type
int rank = 1 ;
Type elem = type . GetElementType ( ) ;
while ( elem . IsArray )
{
rank + + ;
elem = elem . GetElementType ( ) ;
}
wrapper = GetWrapperFromType ( elem ) ;
return wrapper . MakeArrayType ( rank ) ;
2003-02-17 13:13:16 +03:00
}
2005-06-01 13:49:30 +04:00
// if the wrapper doesn't already exist, that must mean that the type
// is a .NET type (or a pre-compiled Java class), which means that it
2006-05-15 13:08:01 +04:00
// was "loaded" by an assembly classloader
return GetAssemblyClassLoader ( type . Assembly ) . GetWrapperFromBootstrapType ( type ) ;
2003-02-17 13:13:16 +03:00
}
2005-06-01 13:49:30 +04:00
return wrapper ;
2002-12-18 19:00:25 +03:00
}
2006-05-15 13:08:01 +04:00
// this method only supports .NET or pre-compiled Java assemblies
internal static ClassLoaderWrapper GetAssemblyClassLoader ( Assembly assembly )
{
// TODO this assertion fires when compiling the core library (at least on Whidbey)
// I need to find out why...
Debug . Assert ( ! ( assembly is AssemblyBuilder ) ) ;
#if WHIDBEY & & ! STATIC_COMPILER
if ( assembly . ReflectionOnly )
{
lock ( reflectionOnlyClassLoaders )
{
ClassLoaderWrapper loader = ( ClassLoaderWrapper ) reflectionOnlyClassLoaders [ assembly ] ;
if ( loader = = null )
{
loader = new ReflectionOnlyClassLoader ( ) ;
reflectionOnlyClassLoaders [ assembly ] = loader ;
}
return loader ;
}
}
#endif
return GetBootstrapClassLoader ( ) ;
}
2005-06-01 13:49:30 +04:00
internal static void SetWrapperForType ( Type type , TypeWrapper wrapper )
{
TypeWrapper . AssertFinished ( type ) ;
Debug . Assert ( ! typeToTypeWrapper . ContainsKey ( type ) ) ;
typeToTypeWrapper . Add ( type , wrapper ) ;
}
2004-11-23 20:46:39 +03:00
2006-04-10 13:09:09 +04:00
#if STATIC_COMPILER
2005-06-01 13:49:30 +04:00
internal static void PublishLibraryImplementationHelperType ( Type type )
2003-12-24 14:51:41 +03:00
{
2005-06-01 13:49:30 +04:00
CompiledTypeWrapper typeWrapper = CompiledTypeWrapper . newInstance ( type . FullName , type ) ;
SetWrapperForType ( type , typeWrapper ) ;
GetBootstrapClassLoader ( ) . types [ type . FullName ] = typeWrapper ;
2003-12-24 14:51:41 +03:00
}
2006-04-10 13:09:09 +04:00
#endif // STATIC_COMPILER
2005-06-01 13:49:30 +04:00
internal static TypeWrapper LoadClassCritical ( string name )
2003-12-24 14:51:41 +03:00
{
2005-06-01 13:49:30 +04:00
try
{
return GetBootstrapClassLoader ( ) . LoadClassByDottedName ( name ) ;
}
catch ( Exception x )
{
JVM . CriticalFailure ( "Loading of critical class failed" , x ) ;
return null ;
}
2003-12-24 14:51:41 +03:00
}
2004-08-30 19:56:23 +04:00
2005-06-01 13:49:30 +04:00
internal void RegisterNativeLibrary ( IntPtr p )
2004-08-30 19:56:23 +04:00
{
2005-06-01 13:49:30 +04:00
lock ( this )
2004-08-30 19:56:23 +04:00
{
2005-06-01 13:49:30 +04:00
if ( nativeLibraries = = null )
{
nativeLibraries = new ArrayList ( ) ;
}
nativeLibraries . Add ( p ) ;
2004-08-30 19:56:23 +04:00
}
}
2005-06-01 13:49:30 +04:00
internal IntPtr [ ] GetNativeLibraries ( )
2004-08-30 19:56:23 +04:00
{
2005-06-01 13:49:30 +04:00
lock ( this )
2004-08-30 19:56:23 +04:00
{
2005-06-01 13:49:30 +04:00
if ( nativeLibraries = = null )
{
return new IntPtr [ 0 ] ;
}
return ( IntPtr [ ] ) nativeLibraries . ToArray ( typeof ( IntPtr ) ) ;
2004-08-30 19:56:23 +04:00
}
}
2005-02-23 15:56:15 +03:00
2005-06-01 13:49:30 +04:00
public override string ToString ( )
2005-02-23 15:56:15 +03:00
{
2005-06-01 13:49:30 +04:00
if ( javaClassLoader = = null )
{
return "null" ;
}
return String . Format ( "{0}@{1:X}" , GetWrapperFromType ( javaClassLoader . GetType ( ) ) . Name , javaClassLoader . GetHashCode ( ) ) ;
2005-02-23 15:56:15 +03:00
}
}
2006-02-22 17:44:07 +03:00
class BootstrapClassLoader : ClassLoaderWrapper
{
internal BootstrapClassLoader ( )
: base ( null )
{
}
}
2006-05-15 13:08:01 +04:00
class ReflectionOnlyClassLoader : ClassLoaderWrapper
{
internal ReflectionOnlyClassLoader ( )
: base ( null )
{
}
}
2002-12-18 19:00:25 +03:00
}