2007-06-13 15:46:24 +04:00
|
|
|
/*
|
|
|
|
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Jeroen Frijters
|
|
|
|
|
|
|
|
This software is provided 'as-is', without any express or implied
|
|
|
|
warranty. In no event will the authors be held liable for any damages
|
|
|
|
arising from the use of this software.
|
|
|
|
|
|
|
|
Permission is granted to anyone to use this software for any purpose,
|
|
|
|
including commercial applications, and to alter it and redistribute it
|
|
|
|
freely, subject to the following restrictions:
|
|
|
|
|
|
|
|
1. The origin of this software must not be misrepresented; you must not
|
|
|
|
claim that you wrote the original software. If you use this software
|
|
|
|
in a product, an acknowledgment in the product documentation would be
|
|
|
|
appreciated but is not required.
|
|
|
|
2. Altered source versions must be plainly marked as such, and must not be
|
|
|
|
misrepresented as being the original software.
|
|
|
|
3. This notice may not be removed or altered from any source distribution.
|
|
|
|
|
|
|
|
Jeroen Frijters
|
|
|
|
jeroen@frijters.net
|
|
|
|
|
|
|
|
*/
|
|
|
|
using System;
|
|
|
|
using System.IO;
|
|
|
|
using System.Reflection;
|
|
|
|
using IKVM.Attributes;
|
|
|
|
using IKVM.Runtime;
|
|
|
|
using IKVM.Internal;
|
2007-10-18 17:54:11 +04:00
|
|
|
using AssemblyClassLoader_ = IKVM.Internal.AssemblyClassLoader;
|
2007-06-13 15:46:24 +04:00
|
|
|
#if !FIRST_PASS
|
|
|
|
using NegativeArraySizeException = java.lang.NegativeArraySizeException;
|
|
|
|
using IllegalArgumentException = java.lang.IllegalArgumentException;
|
|
|
|
using IllegalAccessException = java.lang.IllegalAccessException;
|
|
|
|
using NumberFormatException = java.lang.NumberFormatException;
|
|
|
|
using jlNoClassDefFoundError = java.lang.NoClassDefFoundError;
|
|
|
|
using jlrConstructor = java.lang.reflect.Constructor;
|
|
|
|
using jlrField = java.lang.reflect.Field;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
namespace IKVM.NativeCode.gnu.java.net.protocol.ikvmres
|
|
|
|
{
|
2007-12-18 14:05:30 +03:00
|
|
|
static class Handler
|
2007-06-13 15:46:24 +04:00
|
|
|
{
|
|
|
|
public static Stream ReadResourceFromAssemblyImpl(Assembly asm, string resource)
|
|
|
|
{
|
|
|
|
// chop off the leading slash
|
|
|
|
resource = resource.Substring(1);
|
|
|
|
string mangledName = JVM.MangleResourceName(resource);
|
|
|
|
ManifestResourceInfo info = asm.GetManifestResourceInfo(mangledName);
|
|
|
|
if(info != null && info.FileName != null)
|
|
|
|
{
|
|
|
|
return asm.GetManifestResourceStream(mangledName);
|
|
|
|
}
|
|
|
|
Stream s = asm.GetManifestResourceStream(mangledName);
|
|
|
|
if(s == null)
|
|
|
|
{
|
|
|
|
Tracer.Warning(Tracer.ClassLoading, "Resource \"{0}\" not found in {1}", resource, asm.FullName);
|
|
|
|
throw new FileNotFoundException("resource " + resource + " not found in assembly " + asm.FullName);
|
|
|
|
}
|
|
|
|
switch (s.ReadByte())
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
Tracer.Info(Tracer.ClassLoading, "Reading resource \"{0}\" from {1}", resource, asm.FullName);
|
|
|
|
return s;
|
|
|
|
case 1:
|
|
|
|
Tracer.Info(Tracer.ClassLoading, "Reading compressed resource \"{0}\" from {1}", resource, asm.FullName);
|
|
|
|
return new System.IO.Compression.DeflateStream(s, System.IO.Compression.CompressionMode.Decompress, false);
|
|
|
|
default:
|
|
|
|
Tracer.Error(Tracer.ClassLoading, "Resource \"{0}\" in {1} has an unsupported encoding", resource, asm.FullName);
|
|
|
|
throw new IOException("Unsupported resource encoding for resource " + resource + " found in assembly " + asm.FullName);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static object LoadClassFromAssembly(Assembly asm, string className)
|
|
|
|
{
|
|
|
|
TypeWrapper tw = ClassLoaderWrapper.GetAssemblyClassLoader(asm).LoadClassByDottedNameFast(className);
|
|
|
|
if(tw != null)
|
|
|
|
{
|
|
|
|
return tw.ClassObject;
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static Assembly LoadAssembly(string name)
|
|
|
|
{
|
|
|
|
if(name.EndsWith("[ReflectionOnly]"))
|
|
|
|
{
|
|
|
|
return Assembly.ReflectionOnlyLoad(name.Substring(0, name.Length - 16));
|
|
|
|
}
|
|
|
|
return Assembly.Load(name);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static object GetGenericClassLoaderById(int id)
|
|
|
|
{
|
|
|
|
return ClassLoaderWrapper.GetGenericClassLoaderById(id).GetJavaClassLoader();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-07-03 09:55:58 +04:00
|
|
|
namespace IKVM.NativeCode.java.lang
|
2007-08-22 15:47:22 +04:00
|
|
|
{
|
2007-12-18 14:05:30 +03:00
|
|
|
static class VMSystemProperties
|
2007-08-22 15:47:22 +04:00
|
|
|
{
|
|
|
|
public static string getVersion()
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
return JVM.SafeGetAssemblyVersion(typeof(VMSystemProperties).Assembly).ToString();
|
|
|
|
}
|
|
|
|
catch(Exception)
|
|
|
|
{
|
|
|
|
return "(unknown)";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-06-13 15:46:24 +04:00
|
|
|
namespace IKVM.NativeCode.ikvm.@internal
|
2007-10-25 16:56:18 +04:00
|
|
|
{
|
2008-05-31 19:20:29 +04:00
|
|
|
static class CallerID
|
|
|
|
{
|
|
|
|
public static object GetClass(object obj)
|
|
|
|
{
|
|
|
|
return ClassLoaderWrapper.GetWrapperFromType(obj.GetType().DeclaringType).ClassObject;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static object GetClassLoader(object obj)
|
|
|
|
{
|
|
|
|
return ClassLoaderWrapper.GetWrapperFromType(obj.GetType().DeclaringType).GetClassLoader().GetJavaClassLoader();
|
|
|
|
}
|
|
|
|
|
|
|
|
public static object GetAssemblyClassLoader(Assembly asm)
|
|
|
|
{
|
|
|
|
return ClassLoaderWrapper.GetAssemblyClassLoader(asm).GetJavaClassLoader();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-10-25 16:56:18 +04:00
|
|
|
namespace stubgen
|
|
|
|
{
|
2007-12-18 14:05:30 +03:00
|
|
|
static class StubGenerator
|
2007-10-25 16:56:18 +04:00
|
|
|
{
|
|
|
|
public static string getAssemblyName(object c)
|
|
|
|
{
|
2009-02-04 10:24:44 +03:00
|
|
|
TypeWrapper wrapper = TypeWrapper.FromClass(c);
|
|
|
|
ClassLoaderWrapper loader = wrapper.GetClassLoader();
|
2007-10-25 16:56:18 +04:00
|
|
|
IKVM.Internal.AssemblyClassLoader acl = loader as IKVM.Internal.AssemblyClassLoader;
|
|
|
|
if(acl != null)
|
|
|
|
{
|
2009-02-04 10:24:44 +03:00
|
|
|
return acl.GetAssembly(wrapper).FullName;
|
2007-10-25 16:56:18 +04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return ((IKVM.Internal.GenericClassLoader)loader).GetName();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static object getFieldConstantValue(object field)
|
|
|
|
{
|
|
|
|
return FieldWrapper.FromField(field).GetConstant();
|
|
|
|
}
|
|
|
|
|
|
|
|
public static bool isFieldDeprecated(object field)
|
|
|
|
{
|
|
|
|
FieldWrapper fieldWrapper = FieldWrapper.FromField(field);
|
|
|
|
FieldInfo fi = fieldWrapper.GetField();
|
|
|
|
if(fi != null)
|
|
|
|
{
|
|
|
|
return AttributeHelper.IsDefined(fi, typeof(ObsoleteAttribute));
|
|
|
|
}
|
|
|
|
GetterFieldWrapper getter = fieldWrapper as GetterFieldWrapper;
|
|
|
|
if(getter != null)
|
|
|
|
{
|
|
|
|
return AttributeHelper.IsDefined(getter.GetProperty(), typeof(ObsoleteAttribute));
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static bool isMethodDeprecated(object method)
|
|
|
|
{
|
|
|
|
MethodWrapper mw = MethodWrapper.FromMethodOrConstructor(method);
|
|
|
|
MethodBase mb = mw.GetMethod();
|
|
|
|
return mb != null && AttributeHelper.IsDefined(mb, typeof(ObsoleteAttribute));
|
|
|
|
}
|
|
|
|
|
|
|
|
public static bool isClassDeprecated(object clazz)
|
|
|
|
{
|
|
|
|
Type type = TypeWrapper.FromClass(clazz).TypeAsTBD;
|
|
|
|
// we need to check type for null, because ReflectionOnly
|
|
|
|
// generated delegate inner interfaces don't really exist
|
|
|
|
return type != null && AttributeHelper.IsDefined(type, typeof(ObsoleteAttribute));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace IKVM.NativeCode.ikvm.runtime
|
2007-06-13 15:46:24 +04:00
|
|
|
{
|
2007-12-18 14:05:30 +03:00
|
|
|
static class AssemblyClassLoader
|
2007-06-13 15:46:24 +04:00
|
|
|
{
|
2007-10-22 09:13:08 +04:00
|
|
|
public static object LoadClass(object classLoader, Assembly assembly, string name)
|
2007-06-13 15:46:24 +04:00
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
2007-10-18 17:54:11 +04:00
|
|
|
TypeWrapper tw = null;
|
|
|
|
if(classLoader == null)
|
|
|
|
{
|
|
|
|
tw = ClassLoaderWrapper.GetBootstrapClassLoader().LoadClassByDottedName(name);
|
|
|
|
}
|
2007-10-22 09:13:08 +04:00
|
|
|
else if(assembly != null)
|
2007-10-18 17:54:11 +04:00
|
|
|
{
|
2007-10-22 09:13:08 +04:00
|
|
|
AssemblyClassLoader_ acl = ClassLoaderWrapper.GetAssemblyClassLoader(assembly);
|
2007-10-26 11:11:17 +04:00
|
|
|
tw = acl.GetLoadedClass(name);
|
|
|
|
if(tw == null)
|
2007-10-18 17:54:11 +04:00
|
|
|
{
|
2007-10-22 09:13:08 +04:00
|
|
|
tw = acl.LoadGenericClass(name);
|
2007-10-18 17:54:11 +04:00
|
|
|
}
|
2007-10-22 09:13:08 +04:00
|
|
|
if(tw == null)
|
2007-10-18 17:54:11 +04:00
|
|
|
{
|
2007-10-26 11:11:17 +04:00
|
|
|
tw = acl.LoadReferenced(name);
|
2007-10-18 17:54:11 +04:00
|
|
|
}
|
2007-10-22 09:13:08 +04:00
|
|
|
if(tw == null)
|
|
|
|
{
|
|
|
|
throw new ClassNotFoundException(name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// this must be a GenericClassLoader
|
|
|
|
tw = ((GenericClassLoader)ClassLoaderWrapper.GetClassLoaderWrapper(classLoader)).LoadClassByDottedName(name);
|
2007-10-18 17:54:11 +04:00
|
|
|
}
|
2007-06-13 15:46:24 +04:00
|
|
|
Tracer.Info(Tracer.ClassLoading, "Loaded class \"{0}\" from {1}", name, classLoader == null ? "boot class loader" : classLoader);
|
|
|
|
return tw.ClassObject;
|
|
|
|
}
|
|
|
|
catch(RetargetableJavaException x)
|
|
|
|
{
|
|
|
|
Tracer.Info(Tracer.ClassLoading, "Failed to load class \"{0}\" from {1}", name, classLoader == null ? "boot class loader" : classLoader);
|
|
|
|
throw x.ToJava();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-10-22 09:13:08 +04:00
|
|
|
public static Assembly[] FindResourceAssemblies(Assembly assembly, string name, bool firstOnly)
|
2007-06-13 15:46:24 +04:00
|
|
|
{
|
2007-10-22 09:13:08 +04:00
|
|
|
IKVM.Internal.AssemblyClassLoader wrapper = ClassLoaderWrapper.GetAssemblyClassLoader(assembly);
|
2007-06-13 15:46:24 +04:00
|
|
|
Assembly[] assemblies = wrapper.FindResourceAssemblies(name, firstOnly);
|
|
|
|
if(assemblies == null || assemblies.Length == 0)
|
|
|
|
{
|
2009-02-04 10:24:44 +03:00
|
|
|
Tracer.Info(Tracer.ClassLoading, "Failed to find resource \"{0}\" in {1}", name, assembly.FullName);
|
2007-06-13 15:46:24 +04:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
foreach(Assembly asm in assemblies)
|
|
|
|
{
|
|
|
|
Tracer.Info(Tracer.ClassLoading, "Found resource \"{0}\" in {1}", name, asm.FullName);
|
|
|
|
}
|
|
|
|
return assemblies;
|
|
|
|
}
|
|
|
|
|
2009-02-04 10:24:44 +03:00
|
|
|
public static Assembly GetAssemblyFromClass(object clazz)
|
2007-10-22 09:13:08 +04:00
|
|
|
{
|
2009-02-04 10:24:44 +03:00
|
|
|
TypeWrapper wrapper = TypeWrapper.FromClass(clazz);
|
|
|
|
AssemblyClassLoader_ acl = wrapper.GetClassLoader() as AssemblyClassLoader_;
|
|
|
|
return acl != null ? acl.GetAssembly(wrapper) : null;
|
2007-10-22 09:13:08 +04:00
|
|
|
}
|
|
|
|
|
2007-06-13 15:46:24 +04:00
|
|
|
// NOTE the array may contain duplicates!
|
2007-10-22 09:13:08 +04:00
|
|
|
public static string[] GetPackages(Assembly assembly)
|
2007-06-13 15:46:24 +04:00
|
|
|
{
|
2007-10-22 09:13:08 +04:00
|
|
|
IKVM.Internal.AssemblyClassLoader wrapper = ClassLoaderWrapper.GetAssemblyClassLoader(assembly);
|
2007-06-13 15:46:24 +04:00
|
|
|
string[] packages = new string[0];
|
2009-02-10 10:27:25 +03:00
|
|
|
foreach(Module m in wrapper.MainAssembly.GetModules(false))
|
2007-06-13 15:46:24 +04:00
|
|
|
{
|
|
|
|
object[] attr = m.GetCustomAttributes(typeof(PackageListAttribute), false);
|
|
|
|
foreach(PackageListAttribute p in attr)
|
|
|
|
{
|
|
|
|
string[] mp = p.GetPackages();
|
|
|
|
string[] tmp = new string[packages.Length + mp.Length];
|
|
|
|
Array.Copy(packages, 0, tmp, 0, packages.Length);
|
|
|
|
Array.Copy(mp, 0, tmp, packages.Length, mp.Length);
|
|
|
|
packages = tmp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return packages;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static bool IsReflectionOnly(Assembly asm)
|
|
|
|
{
|
|
|
|
return asm.ReflectionOnly;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static int GetGenericClassLoaderId(object classLoader)
|
|
|
|
{
|
2007-12-19 14:28:09 +03:00
|
|
|
#if FIRST_PASS
|
|
|
|
return 0;
|
|
|
|
#else
|
2008-05-20 11:36:50 +04:00
|
|
|
return ClassLoaderWrapper.GetGenericClassLoaderId(ClassLoaderWrapper.GetClassLoaderWrapper(classLoader));
|
2007-12-19 14:28:09 +03:00
|
|
|
#endif
|
2007-06-13 15:46:24 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
public static string GetGenericClassLoaderName(object classLoader)
|
|
|
|
{
|
2007-12-19 14:28:09 +03:00
|
|
|
#if FIRST_PASS
|
|
|
|
return null;
|
|
|
|
#else
|
2008-05-20 11:36:50 +04:00
|
|
|
return ((GenericClassLoader)ClassLoaderWrapper.GetClassLoaderWrapper(classLoader)).GetName();
|
2007-12-19 14:28:09 +03:00
|
|
|
#endif
|
2007-06-13 15:46:24 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-12-18 14:05:30 +03:00
|
|
|
static class AppDomainAssemblyClassLoader
|
2007-10-22 12:09:19 +04:00
|
|
|
{
|
|
|
|
public static object loadClassFromAssembly(Assembly asm, string className)
|
|
|
|
{
|
2009-05-28 09:58:35 +04:00
|
|
|
if(ReflectUtil.IsDynamicAssembly(asm))
|
2007-11-02 08:11:47 +03:00
|
|
|
{
|
|
|
|
return null;
|
|
|
|
}
|
2007-10-22 12:09:19 +04:00
|
|
|
TypeWrapper tw = ClassLoaderWrapper.GetAssemblyClassLoader(asm).DoLoad(className);
|
|
|
|
return tw != null ? tw.ClassObject : null;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static bool findResourceInAssembly(Assembly asm, string resourceName)
|
|
|
|
{
|
2009-05-28 09:58:35 +04:00
|
|
|
if(ReflectUtil.IsDynamicAssembly(asm))
|
2007-11-02 08:11:47 +03:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2007-10-22 12:09:19 +04:00
|
|
|
return asm.GetManifestResourceInfo(JVM.MangleResourceName(resourceName)) != null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-12-18 14:05:30 +03:00
|
|
|
static class Util
|
2007-06-13 15:46:24 +04:00
|
|
|
{
|
|
|
|
public static object getClassFromObject(object o)
|
|
|
|
{
|
|
|
|
return GetTypeWrapperFromObject(o).ClassObject;
|
|
|
|
}
|
|
|
|
|
|
|
|
internal static TypeWrapper GetTypeWrapperFromObject(object o)
|
|
|
|
{
|
2009-02-24 09:11:54 +03:00
|
|
|
TypeWrapper ghostType = GhostTag.GetTag(o);
|
|
|
|
if(ghostType != null)
|
|
|
|
{
|
|
|
|
return ghostType;
|
|
|
|
}
|
2007-06-13 15:46:24 +04:00
|
|
|
Type t = o.GetType();
|
|
|
|
if(t.IsPrimitive || (ClassLoaderWrapper.IsRemappedType(t) && !t.IsSealed))
|
|
|
|
{
|
2009-02-27 08:57:35 +03:00
|
|
|
return DotNetTypeWrapper.GetWrapperFromDotNetType(t);
|
2007-06-13 15:46:24 +04:00
|
|
|
}
|
2009-02-24 09:11:54 +03:00
|
|
|
else
|
2008-08-06 09:25:18 +04:00
|
|
|
{
|
2009-02-27 08:57:35 +03:00
|
|
|
return ClassLoaderWrapper.GetWrapperFromType(t);
|
2008-08-06 09:25:18 +04:00
|
|
|
}
|
2007-06-13 15:46:24 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
public static object getClassFromTypeHandle(RuntimeTypeHandle handle)
|
|
|
|
{
|
|
|
|
Type t = Type.GetTypeFromHandle(handle);
|
|
|
|
if(t.IsPrimitive || ClassLoaderWrapper.IsRemappedType(t) || t == typeof(void))
|
|
|
|
{
|
|
|
|
return DotNetTypeWrapper.GetWrapperFromDotNetType(t).ClassObject;
|
|
|
|
}
|
2007-11-26 12:01:35 +03:00
|
|
|
if(t.ContainsGenericParameters)
|
2007-06-13 15:46:24 +04:00
|
|
|
{
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
TypeWrapper tw = ClassLoaderWrapper.GetWrapperFromType(t);
|
|
|
|
if(tw != null)
|
|
|
|
{
|
|
|
|
return tw.ClassObject;
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static object getFriendlyClassFromType(Type type)
|
|
|
|
{
|
2007-11-26 12:01:35 +03:00
|
|
|
if(type.ContainsGenericParameters)
|
2007-06-13 15:46:24 +04:00
|
|
|
{
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
int rank = 0;
|
|
|
|
while(type.IsArray)
|
|
|
|
{
|
|
|
|
type = type.GetElementType();
|
|
|
|
rank++;
|
|
|
|
}
|
|
|
|
if(type.DeclaringType != null
|
|
|
|
&& AttributeHelper.IsGhostInterface(type.DeclaringType))
|
|
|
|
{
|
|
|
|
type = type.DeclaringType;
|
|
|
|
}
|
|
|
|
TypeWrapper wrapper = ClassLoaderWrapper.GetWrapperFromType(type);
|
2007-09-11 16:06:21 +04:00
|
|
|
if(wrapper == null)
|
|
|
|
{
|
|
|
|
return null;
|
|
|
|
}
|
2007-06-13 15:46:24 +04:00
|
|
|
if(rank > 0)
|
|
|
|
{
|
|
|
|
wrapper = wrapper.MakeArrayType(rank);
|
|
|
|
}
|
|
|
|
return wrapper.ClassObject;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static Type getInstanceTypeFromClass(object clazz)
|
|
|
|
{
|
|
|
|
TypeWrapper wrapper = TypeWrapper.FromClass(clazz);
|
|
|
|
if(wrapper.IsRemapped && wrapper.IsFinal)
|
|
|
|
{
|
|
|
|
return wrapper.TypeAsTBD;
|
|
|
|
}
|
|
|
|
return wrapper.TypeAsBaseType;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|